回答編集履歴

5

テキスト修正

2020/08/28 01:00

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -104,7 +104,7 @@
104
104
 
105
105
  ```
106
106
 
107
- は使えないので、オブジェクトの値として、他の作り方を検討する必要があります。このご質問のような課題の解決の際に、各オブジェクトの等値性を判定するための値(言い換えると、各オブジェクトを何らかのクラスのインタンスとして得ることにした場合に、そのクラスの`valueOf`メソッドが返す値)をうまく決められるかどうか、というのがひとつのになります。
107
+ は使えないので、オブジェクトの値(value)別の作り方を検討する必要があります。このご質問のような課題の解決の際に、各オブジェクトの等値性を判定するための値(言い換えると、各オブジェクトを何らかのクラスのインタンスとして得ることにした場合に、そのクラスの`valueOf`メソッドが返す値)をうまく決められるかどうか、というのがひとつの検討事項になります。
108
108
 
109
109
 
110
110
 

4

テキスト修正

2020/08/28 01:00

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -109,3 +109,13 @@
109
109
 
110
110
 
111
111
  以上、参考になれば幸いです。
112
+
113
+
114
+
115
+ ### 追記
116
+
117
+
118
+
119
+ はじめに挙げた、Set を使うコードのほうで、Setのインスタンスをnewで作るコストが気になるようであれば、Setの替わりにプレーンオブジェクトを使うこともできます。
120
+
121
+ - **動作確認用 codepen.io:** [jun68ykt/pen/KKzmGLM](https://codepen.io/jun68ykt/pen/KKzmGLM?editors=0012)

3

テキスト修正

2020/08/28 00:16

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -78,7 +78,7 @@
78
78
 
79
79
 
80
80
 
81
- ただし、上記はオブジェクトの等値判定に、汎用的な `_.isEqual`を使っているので、やや非効率です。先と同様にオブジェクトの値(value)を定義できるのであれば、オブジェクトの値を取得するメソッド`valueOf`を作っておいて、等値判定のためにこれを利用できます。以下はその例です。
81
+ ただし、上記はオブジェクトの等値判定に、汎用的な `_.isEqual`を使っているところが非効率です。先と同様にオブジェクトの値(value)を定義できるのであれば、オブジェクトの値を取得するメソッド`valueOf`を作っておいて、等値判定のためにこれを利用できます。以下はその例です。
82
82
 
83
83
 
84
84
 

2

テキスト修正

2020/08/27 23:59

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -104,7 +104,7 @@
104
104
 
105
105
  ```
106
106
 
107
- は使えないので、オブジェクトの値として、他の作り方を検討する必要があります。
107
+ は使えないので、オブジェクトの値として、他の作り方を検討する必要があります。このご質問のような課題の解決の際に、各オブジェクトの等値性を判定するための値(言い換えると、各オブジェクトを何らかのクラスのインタンスとして得ることにした場合に、そのクラスの`valueOf`メソッドが返す値)をうまく決められるかどうか、というのがひとつの鍵になります。
108
108
 
109
109
 
110
110
 

1

テキスト修正

2020/08/27 22:59

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -1,8 +1,4 @@
1
1
  こんにちは
2
-
3
-
4
-
5
- 配列やオブジェクトの操作で便利なライブラリ [lodash](https://lodash.com/) を使った回答になります。
6
2
 
7
3
 
8
4
 
@@ -18,6 +14,58 @@
18
14
 
19
15
 
20
16
 
17
+ ### Set を使用
18
+
19
+
20
+
21
+ 重複をチェックするために Set を使います。
22
+
23
+
24
+
25
+ 各オブジェクトの `name` は、アルファベットのみから構成される文字列であると仮定とすると、各オブジェクトの等値性は、`id`, `name`, `course_id` の順に値を連結して得られる文字列を比較すればよいことになります。この文字列を各要素の**値(value)**と呼ぶことにすると、items に出現する各要素の値を、Set に格納していけば、重複チェックの計算量をO(1)で済ませることができます。
26
+
27
+
28
+
29
+ ```javascript
30
+
31
+ const set = new Set();
32
+
33
+
34
+
35
+ const target = items.filter(e => {
36
+
37
+ const value = `${e.id}${e.name}${e.course_id}`;
38
+
39
+ if (set.has(value)) {
40
+
41
+ return false;
42
+
43
+ } else {
44
+
45
+ set.add(value);
46
+
47
+ return true;
48
+
49
+ }
50
+
51
+ });
52
+
53
+ ```
54
+
55
+ - **動作確認用 codepen.io:** [jun68ykt/pen/poyPOVG](https://codepen.io/jun68ykt/pen/poyPOVG?editors=0012)
56
+
57
+
58
+
59
+
60
+
61
+ ### lodash を使用
62
+
63
+
64
+
65
+ 配列やオブジェクトの操作で便利なライブラリ [lodash](https://lodash.com/) を使うと以下のように手短かに書けます。
66
+
67
+
68
+
21
69
  ```javascript
22
70
 
23
71
  const target = _.uniqWith(items, _.isEqual);
@@ -28,4 +76,36 @@
28
76
 
29
77
 
30
78
 
79
+
80
+
81
+ ただし、上記はオブジェクトの等値判定に、汎用的な `_.isEqual`を使っているので、やや非効率です。先と同様にオブジェクトの値(value)を定義できるのであれば、オブジェクトの値を取得するメソッド`valueOf`を作っておいて、等値判定のためにこれを利用できます。以下はその例です。
82
+
83
+
84
+
85
+ ```javascript
86
+
87
+ const valueOf = e => `${e.id}${e.name}${e.course_id}`;
88
+
89
+
90
+
91
+ const target = _.uniqBy(items, valueOf);
92
+
93
+ ```
94
+
95
+ - **動作確認用 codepen.io:** [jun68ykt/pen/eYZWLam](https://codepen.io/jun68ykt/pen/eYZWLam?editors=0012)
96
+
97
+
98
+
99
+ なお、`name` プロパティに、`'9apple'` や `'lemon3'` といったような、数字で始まる、または数字で終わる文字列が出現する可能性があるならば、オブジェクトの等値性を判定する値として、
100
+
101
+ ```javascript
102
+
103
+ `${e.id}${e.name}${e.course_id}`
104
+
105
+ ```
106
+
107
+ は使えないので、オブジェクトの値として、他の作り方を検討する必要があります。
108
+
109
+
110
+
31
- 参考になれば幸いです。
111
+ 以上、参考になれば幸いです。