回答編集履歴

27

テキスト修正

2019/11/16 08:42

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -266,7 +266,7 @@
266
266
 
267
267
 
268
268
 
269
- アルゴリズムとしては、`getUnique8` を拝借し、比較対象として、0以上の整数として設定される id(`const id = 1000 * x + y;`) を使うコードです。
269
+ アルゴリズムとしては、`getUnique8` を拝借し、比較対象として、0以上の整数として設定される id(=`1000 * x + y`) を使うコードです。
270
270
 
271
271
 
272
272
 

26

テキスト修正

2019/11/16 08:42

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -356,7 +356,7 @@
356
356
 
357
357
 
358
358
 
359
- とはいえ、実際の何らかの問題領域においては、配列要素となるオブジェクトの型は何らか特定できるものなので、その型情報から、問題領域に出現し得るオブジェクト群が全順序を満たすような何らかの大小比較関数、あるいは大小の比較が可能な(今回の `id`プロパティ のような)そのオブジェクトのプリミティブ値(※)を導入できるかどうか検討することが、ある型を要素とする配列の差分抽出には優先順位の高いタスクかなと思われました。その結果、もし(運良大小関係を定義できれば、`getUnique8`をベースとした速いコードを書くことができます。
359
+ とはいえ、実際の何らかの問題領域においては、配列要素となるオブジェクトの型は何らか特定できるものなので、その型情報から、問題領域に出現し得るオブジェクト群が全順序を満たすような何らかの大小比較関数、あるいは大小の比較が可能な(今回の `id`プロパティ のような)そのオブジェクトのプリミティブ値(※)を導入できるかどうか検討することが、ある型を要素とする配列の差分抽出には優先順位の高いタスクかなと思われました。その結果、うまく大小関係を定義できれば、`getUnique8`をベースとした速いコードを書くことができます。
360
360
 
361
361
 
362
362
 

25

テキスト修正

2019/11/16 07:05

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -356,7 +356,7 @@
356
356
 
357
357
 
358
358
 
359
- とはいえ、実際の何らかの問題領域においては、配列要素となるオブジェクトの型は何らか特定できるものなので、その型情報から、問題領域に出現し得るオブジェクト群が全順序を満たすような何らかの大小比較関数、あるいは大小の比較が可能な(今回の `id`プロパティ のような)そのオブジェクトのプリミティブ値(※)を導入できるかどうか検討することが、ある型を要素とする配列の差分抽出には優先順位の高いタスクかなと思われました。
359
+ とはいえ、実際の何らかの問題領域においては、配列要素となるオブジェクトの型は何らか特定できるものなので、その型情報から、問題領域に出現し得るオブジェクト群が全順序を満たすような何らかの大小比較関数、あるいは大小の比較が可能な(今回の `id`プロパティ のような)そのオブジェクトのプリミティブ値(※)を導入できるかどうか検討することが、ある型を要素とする配列の差分抽出には優先順位の高いタスクかなと思われました。その結果、もし(運良く)大小関係を定義できれば、`getUnique8`をベースとした速いコードを書くことができます。
360
360
 
361
361
 
362
362
 

24

テキスト修正

2019/11/16 06:48

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -360,4 +360,4 @@
360
360
 
361
361
 
362
362
 
363
- ※このような「そのオブジェクトの値を表すプリミティブ値を返す」ために、対象とするオブジェクト群専用の [valueOf()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf) メソッドが定義される場合があります。
363
+ 参考:このような「そのオブジェクトの値を表すプリミティブ値を返す」ために、対象とするオブジェクト群専用の [valueOf()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf) メソッドが定義される場合があります。

23

テキスト修正

2019/11/16 06:44

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -356,7 +356,7 @@
356
356
 
357
357
 
358
358
 
359
- とはいえ、実際の何らかの問題領域においては、配列要素となるオブジェクトの型は何らか特定できるものなので、その型情報から、問題領域に出現し得るオブジェクト群が全順序を満たすような何らかの大小比較関数、あるいは大小の比較が可能な(今回の `id` のような)そのオブジェクトのプリミティブ値(※)を導入できるかどうか検討することが、ある型を要素とする配列の差分抽出には優先順位の高いタスクかなと思われました。
359
+ とはいえ、実際の何らかの問題領域においては、配列要素となるオブジェクトの型は何らか特定できるものなので、その型情報から、問題領域に出現し得るオブジェクト群が全順序を満たすような何らかの大小比較関数、あるいは大小の比較が可能な(今回の `id`プロパティ のような)そのオブジェクトのプリミティブ値(※)を導入できるかどうか検討することが、ある型を要素とする配列の差分抽出には優先順位の高いタスクかなと思われました。
360
360
 
361
361
 
362
362
 

22

テキスト修正

2019/11/16 06:42

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -340,7 +340,7 @@
340
340
 
341
341
  ```
342
342
 
343
- という型を満たしているという前提が明らかになっていれば、これを元に、問題の対象範囲に出現するオブジェクトの集合が全順序集合になるような、何らかの大小関係を定義できて(つまり、ソート結果が一意な大小関係を定義できて)、Set や Map を使わない `getUnique13`やその元となっている `getUnique8`のようなコードを書けますが、もし、`a` や `b` の要素として入ってくるオブジェクトの型が不明という状況、すなわち、ご質問のタイトルにある
343
+ という型を満たしているという前提が明らかになっていれば、これを元に、問題の対象範囲に出現するオブジェクトの集合が全順序集合になるような、何らかの大小関係(つまり、ソート結果が一意る比較関数)を定義できるかどうか検討することができて、もし(運良く)大小関係を定義できれば、Set や Map を使わない `getUnique13`やその元となっている `getUnique8`のようなコードを書けますが、もし、`a` や `b` の要素として入ってくるオブジェクトの型が不明という状況、すなわち、ご質問のタイトルにある
344
344
 
345
345
  「二つの配列、それぞれに含まれるユニークな値をできるだけ高速に抽出する方法」
346
346
 

21

テキスト修正

2019/11/16 06:37

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -340,7 +340,11 @@
340
340
 
341
341
  ```
342
342
 
343
- という型を満たしているという前提が明らかになっていれば、これを元に、問題の対象範囲に出現するオブジェクトの集合が全順序集合になるような、何らかの大小関係を定義できて(つまり、ソート結果が一意な比較を定義できて)、Set や Map を使わない `getUnique13`やその元となっている `getUnique8`のようなコードを書けますが、もし、`a` や `b` の要素として入ってくるオブジェクトの型が不明という状況だと回答の冒頭挙げた
343
+ という型を満たしているという前提が明らかになっていれば、これを元に、問題の対象範囲に出現するオブジェクトの集合が全順序集合になるような、何らかの大小関係を定義できて(つまり、ソート結果が一意な大小を定義できて)、Set や Map を使わない `getUnique13`やその元となっている `getUnique8`のようなコードを書けますが、もし、`a` や `b` の要素として入ってくるオブジェクトの型が不明という状況、すなわち、ご質問タイトルある
344
+
345
+ 「二つの配列、それぞれに含まれるユニークな値をできるだけ高速に抽出する方法」
346
+
347
+ の一般解を求めようとすると、この回答の冒頭に挙げた
344
348
 
345
349
  ```javascript
346
350
 
@@ -352,4 +356,8 @@
352
356
 
353
357
 
354
358
 
355
- とはいえ、実際の何らかの問題領域においては、配列要素となるオブジェクトの型は何らか特定できるものなので、その型情報から、問題領域に出現し得るオブジェクト群が全順序を満たすような何らかの比較関数、あるいは比較可能な(今回の `id` のような)そのオブジェクトのプリミティブ値を導入できないかどうか検討することが、ある型を要素とする配列の差分抽出には優先順位の高いタスクかなと思われました。
359
+ とはいえ、実際の何らかの問題領域においては、配列要素となるオブジェクトの型は何らか特定できるものなので、その型情報から、問題領域に出現し得るオブジェクト群が全順序を満たすような何らかの大小比較関数、あるいは大小の比較可能な(今回の `id` のような)そのオブジェクトのプリミティブ値(※)を導入できかどうか検討することが、ある型を要素とする配列の差分抽出には優先順位の高いタスクかなと思われました。
360
+
361
+
362
+
363
+ ※このような「そのオブジェクトの値を表すプリミティブ値を返す」ために、対象とするオブジェクト群専用の [valueOf()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf) メソッドが定義される場合があります。

20

テキスト修正

2019/11/16 06:33

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -323,3 +323,33 @@
323
323
 
324
324
 
325
325
  参考になれば幸いです。
326
+
327
+
328
+
329
+
330
+
331
+ ### 所感
332
+
333
+
334
+
335
+ ご質問のサンプルにあるように、配列`a` 配列 `b` ともにその要素はすべて
336
+
337
+ ```typescript
338
+
339
+ { x: number; y: number }
340
+
341
+ ```
342
+
343
+ という型を満たしているという前提が明らかになっていれば、これを元に、問題の対象範囲に出現するオブジェクトの集合が全順序集合になるような、何らかの大小関係を定義できて(つまり、ソート結果が一意な比較関数を定義できて)、Set や Map を使わない `getUnique13`やその元となっている `getUnique8`のようなコードを書けますが、もし、`a` や `b` の要素として入ってくるオブジェクトの型が不明という状況だと、この回答の冒頭に挙げた
344
+
345
+ ```javascript
346
+
347
+ const getUnique = (a,b) => _.differenceWith(a, b, _.isEqual);
348
+
349
+ ```
350
+
351
+ のような時間のかかるコードに頼らざるを得なくなるのかなという気はいたします。
352
+
353
+
354
+
355
+ とはいえ、実際の何らかの問題領域においては、配列要素となるオブジェクトの型は何らか特定できるものなので、その型情報から、問題領域に出現し得るオブジェクト群が全順序を満たすような何らかの比較関数、あるいは比較可能な(今回の `id` のような)そのオブジェクトのプリミティブ値を導入できないかどうか検討することが、(ある型を要素とする)配列の差分抽出には優先順位の高いタスクかなと思われました。

19

テキスト修正

2019/11/16 06:19

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -292,11 +292,11 @@
292
292
 
293
293
  for (let iA=0, iB=0; iA < lenA || iB < lenB; ) {
294
294
 
295
- if (iB >= lenB || iA < lenA && a[iA].id < b[iB].id) {
295
+ if (iB === lenB || iA < lenA && a[iA].id < b[iB].id) {
296
296
 
297
297
  onlyA.push(a[iA ++]);
298
298
 
299
- } else if (iA >= lenA || iB < lenB && b[iB].id < a[iA].id) {
299
+ } else if (iA === lenA || iB < lenB && b[iB].id < a[iA].id) {
300
300
 
301
301
  onlyB.push(b[iB ++]);
302
302
 
@@ -318,7 +318,7 @@
318
318
 
319
319
  ```
320
320
 
321
- - ** getUnique13:** [https://jsfiddle.net/jun68ykt/h2ydp9sj/10/](https://jsfiddle.net/jun68ykt/h2ydp9sj/10/)
321
+ - ** getUnique13:** [https://jsfiddle.net/jun68ykt/h2ydp9sj/11/](https://jsfiddle.net/jun68ykt/h2ydp9sj/11/)
322
322
 
323
323
 
324
324
 

18

テキスト修正

2019/11/16 05:13

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -262,4 +262,64 @@
262
262
 
263
263
 
264
264
 
265
+ ### 追記 - getUnique13
266
+
267
+
268
+
269
+ アルゴリズムとしては、`getUnique8` を拝借し、比較対象として、0以上の整数として設定される id(`const id = 1000 * x + y;`) を使うコードです。
270
+
271
+
272
+
273
+ ```javascript
274
+
275
+ function getUnique13(a, b) {
276
+
277
+ const lenA = a.length,
278
+
279
+ lenB = b.length,
280
+
281
+ onlyA = [],
282
+
283
+ onlyB = [];
284
+
285
+
286
+
287
+ a.sort((e1, e2) => e1.id - e2.id);
288
+
289
+ b.sort((e1, e2) => e1.id - e2.id);
290
+
291
+
292
+
293
+ for (let iA=0, iB=0; iA < lenA || iB < lenB; ) {
294
+
295
+ if (iB >= lenB || iA < lenA && a[iA].id < b[iB].id) {
296
+
297
+ onlyA.push(a[iA ++]);
298
+
299
+ } else if (iA >= lenA || iB < lenB && b[iB].id < a[iA].id) {
300
+
301
+ onlyB.push(b[iB ++]);
302
+
303
+ } else {
304
+
305
+ iA ++;
306
+
307
+ iB ++;
308
+
309
+ }
310
+
311
+ }
312
+
313
+
314
+
315
+ return [onlyA, onlyB];
316
+
317
+ }
318
+
319
+ ```
320
+
321
+ - ** getUnique13:** [https://jsfiddle.net/jun68ykt/h2ydp9sj/10/](https://jsfiddle.net/jun68ykt/h2ydp9sj/10/)
322
+
323
+
324
+
265
- 以上、参考になれば幸いです。
325
+ 参考になれば幸いです。

17

テキスト修正

2019/11/16 04:46

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -36,7 +36,7 @@
36
36
 
37
37
 
38
38
 
39
- 上記ではlodashを使った汎用的なコードを挙げましたが、コメントから頂きましたjsFiddleのテストコードによって生成されるオブジェクトの配列を処理することに特化して、なるべく高速に処理するコードも考えてみました。以下の `getUnique10` になります。
39
+ 上記ではlodashを使った汎用的なコードを挙げましたが、コメントから頂きましたjsFiddleのテストコードによって生成されるオブジェクトの配列を処理することに特化しコードも考えてみました。以下の `getUnique10` になります。
40
40
 
41
41
 
42
42
 

16

テキスト修正

2019/11/16 02:32

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -258,4 +258,8 @@
258
258
 
259
259
 
260
260
 
261
+ ![イメージ説明](a7bb4474530734b107acd6d278265e54.png)
262
+
263
+
264
+
261
265
  以上、参考になれば幸いです。

15

テキスト修正

2019/11/16 02:03

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -182,7 +182,71 @@
182
182
 
183
183
 
184
184
 
185
- 先述の `getUnique11` のループで使っている、 `for ・・・ of` および `filter` を、 (ofなしの)`for`文に変更した、 `getUnique12` を作成しました。`getUnique11`との比較をするための jsFiddleが下記です。
185
+ 先述の `getUnique11` のループで使っている、 `for ・・・ of` および `filter` を、 (ofなしの)`for`文に変更した、 `getUnique12` を作成しました。
186
+
187
+
188
+
189
+ ```javascript
190
+
191
+ function getUnique12(a, b) {
192
+
193
+ const set = new Set();
194
+
195
+
196
+
197
+ const lenA = a.length;
198
+
199
+ const lenB = b.length;
200
+
201
+
202
+
203
+ for (let i=0; i < lenA; ++ i)
204
+
205
+ set.add(a[i].id);
206
+
207
+
208
+
209
+ for (let i=0; i < lenB; ++ i)
210
+
211
+ set.add(~b[i].id);
212
+
213
+
214
+
215
+ const onlyA = [];
216
+
217
+ for (let i=0; i < lenA; ++ i) {
218
+
219
+ if(!set.has(~a[i].id))
220
+
221
+ onlyA.push(a[i]);
222
+
223
+ }
224
+
225
+
226
+
227
+ const onlyB = [];
228
+
229
+ for (let i=0; i < lenB; ++ i) {
230
+
231
+ if(!set.has(b[i].id))
232
+
233
+ onlyB.push(b[i]);
234
+
235
+ }
236
+
237
+
238
+
239
+ return [onlyA, onlyB];
240
+
241
+ }
242
+
243
+
244
+
245
+ ```
246
+
247
+
248
+
249
+ `getUnique11`との比較をするための jsFiddleが下記です。
186
250
 
187
251
 
188
252
 

14

テキスト修正

2019/11/16 01:51

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -92,7 +92,7 @@
92
92
 
93
93
 
94
94
 
95
- 前掲の `getUnique10` の改良案を挙げます。この改良案は、(コメントには既にきまし、) 下記
95
+ 前掲の `getUnique10` の改良案を挙げます。この改良案は、(2019/11/14 21:10のコメントに書とおり、) 下記
96
96
 
97
97
 
98
98
 

13

テキスト修正

2019/11/16 01:33

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -150,7 +150,7 @@
150
150
 
151
151
  ```
152
152
 
153
- `getUnique10` では 2個の Set を使っていましたが、上記の `getUnique11` では、1個で済ませるようにして、Set 1個分のコンストラクタ `new Set()` の時間を減らすことを狙っています。Setを1個にした替わりに、b の要素の id をSet にaddするときに、それが b の要素のidあることが分かように、ビット反転した値を add ています。
153
+ `getUnique10` では 2個の Set を使っていましたが、上記の `getUnique11` では、1個で済ませるようにして、Set 1個分のコンストラクタ `new Set()` の時間を減らすことを狙っています。Setを1個にした替わりに、b の要素の id をSet にaddするときに、a の要素のidと被らない値に変換する必要がりますが、その変換のために、(整数に対す演算として速いことが期待できビット反転 `~` を使っています。
154
154
 
155
155
 
156
156
 

12

テキスト修正

2019/11/15 21:25

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -92,7 +92,7 @@
92
92
 
93
93
 
94
94
 
95
- 前掲の `getUnique10` の改良案を挙げます。この改良案は、コメントには既に書きました、下記
95
+ 前掲の `getUnique10` の改良案を挙げます。この改良案は、(コメントには既に書きました下記
96
96
 
97
97
 
98
98
 

11

テキスト修正

2019/11/15 21:15

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -78,7 +78,7 @@
78
78
 
79
79
 
80
80
 
81
- - **getUnique10 vs getUnique7:** [https://jsfiddle.net/jun68ykt/b501gqpj/1/](https://jsfiddle.net/jun68ykt/b501gqpj/1/)
81
+ - **getUnique7 vs getUnique10:** [https://jsfiddle.net/jun68ykt/b501gqpj/1/](https://jsfiddle.net/jun68ykt/b501gqpj/1/)
82
82
 
83
83
 
84
84
 

10

テキスト修正

2019/11/15 21:12

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -114,7 +114,7 @@
114
114
 
115
115
  ```
116
116
 
117
- のようなコードによって、 `id` に整数の値を設定することが前提になります。`getUnique11` は以下です。
117
+ のようなコードによって、 `id` に0以上の整数の値を設定することが前提になります。`getUnique11` は以下です。
118
118
 
119
119
 
120
120
 

9

テキスト修正

2019/11/15 20:57

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -114,7 +114,7 @@
114
114
 
115
115
  ```
116
116
 
117
- のようなコードによって、 `id` に数値を設定することが前提になります。`getUnique11` は以下です。
117
+ のようなコードによって、 `id` に値を設定することが前提になります。`getUnique11` は以下です。
118
118
 
119
119
 
120
120
 

8

テキスト修正

2019/11/15 20:52

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -36,7 +36,7 @@
36
36
 
37
37
 
38
38
 
39
- 上記ではlodashを使った汎用的なコードを挙げましたが、コメントから頂きましたjsFiddleのテストコードによって生成さるオブジェクトの配列を処理することに特化して、なるべく高速に処理するコードも考えてみました。以下の `getUnique10` になります。
39
+ 上記ではlodashを使った汎用的なコードを挙げましたが、コメントから頂きましたjsFiddleのテストコードによって生成さるオブジェクトの配列を処理することに特化して、なるべく高速に処理するコードも考えてみました。以下の `getUnique10` になります。
40
40
 
41
41
 
42
42
 

7

テキスト修正

2019/11/15 20:43

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -36,7 +36,7 @@
36
36
 
37
37
 
38
38
 
39
- lodashを使わずに、なるべく高速に処理するコードも考えてみました。以下の `getUnique10` になります。
39
+ 上記ではlodashを使った汎用的なコードを挙げましたが、コメントから頂きました、jsFiddleのテストコードよって生成させるオブジェクトの配列を処理することに特化して、なるべく高速に処理するコードも考えてみました。以下の `getUnique10` になります。
40
40
 
41
41
 
42
42
 
@@ -74,15 +74,15 @@
74
74
 
75
75
 
76
76
 
77
- 上記の `getUnique10` を試すコードを以下の jsFiddle に作成しました。
77
+ の `getUnique10` を試すコードを以下の jsFiddle に作成しました。
78
78
 
79
79
 
80
80
 
81
- - **動作確認用 jsFiddle :** [https://jsfiddle.net/jun68ykt/b501gqpj/1/](https://jsfiddle.net/jun68ykt/b501gqpj/1/)
81
+ - **getUnique10 vs getUnique7:** [https://jsfiddle.net/jun68ykt/b501gqpj/1/](https://jsfiddle.net/jun68ykt/b501gqpj/1/)
82
82
 
83
83
 
84
84
 
85
- これは、コメントからご教示いただきました、 [https://jsfiddle.net/e9a5kvw2/](https://jsfiddle.net/e9a5kvw2/) を Forkして、テスト対象として`getUnique10` を追加したものです。
85
+ 上記は、コメントからご教示いただきました、 [https://jsfiddle.net/e9a5kvw2/](https://jsfiddle.net/e9a5kvw2/) を Forkして、テスト対象として`getUnique10` を追加したものです。
86
86
 
87
87
 
88
88
 

6

テキスト修正

2019/11/15 20:41

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -178,4 +178,20 @@
178
178
 
179
179
 
180
180
 
181
+ ### 追記 - getUnique12
182
+
183
+
184
+
185
+ 先述の `getUnique11` のループで使っている、 `for ・・・ of` および `filter` を、 (ofなしの)`for`文に変更した、 `getUnique12` を作成しました。`getUnique11`との比較をするための jsFiddleが下記です。
186
+
187
+
188
+
189
+ - **getUnique11 vs getUnique12:** [https://jsfiddle.net/jun68ykt/ajtnd5wm/13/](https://jsfiddle.net/jun68ykt/ajtnd5wm/13/)
190
+
191
+
192
+
193
+ 当方の環境では、`getUnique12` のほうが数ミリ〜10ミリ秒程度、短くなる結果を確認しています。 
194
+
195
+
196
+
181
197
  以上、参考になれば幸いです。

5

テキスト修正

2019/11/15 00:58

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -92,7 +92,7 @@
92
92
 
93
93
 
94
94
 
95
- 上記の `getUnique10` の改良案を挙げます。この改良案は、コメントには既に書きました、下記
95
+ 前掲の `getUnique10` の改良案を挙げます。この改良案は、コメントには既に書きました、下記
96
96
 
97
97
 
98
98
 

4

テキスト修正

2019/11/14 15:49

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -92,7 +92,7 @@
92
92
 
93
93
 
94
94
 
95
- 上記の `getUnique10` の改良案を挙げます。ただしこの改良案は、コメントに書ように、下記
95
+ 上記の `getUnique10` の改良案を挙げます。この改良案は、コメントには既にきました、下記
96
96
 
97
97
 
98
98
 
@@ -114,7 +114,7 @@
114
114
 
115
115
  ```
116
116
 
117
- にて、 `id` 数値として設定することが前提になります。`getUnique11` は以下です。
117
+ のようなコードよって、 `id` 数値設定することが前提になります。`getUnique11` は以下です。
118
118
 
119
119
 
120
120
 

3

テキスト修正

2019/11/14 15:03

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -150,7 +150,7 @@
150
150
 
151
151
  ```
152
152
 
153
- `getUnique10` では 2個の Set を使っていましたが、上記の `getUnique11` では、1個で済ませるようにして、Set 1個分のコンストラクタの時間を減らすことを狙っています。Setを1個にした替わりに、b の要素の id をSet にaddするときに、それが b の要素のid であることが分かるように、ビット反転した値を add しています。
153
+ `getUnique10` では 2個の Set を使っていましたが、上記の `getUnique11` では、1個で済ませるようにして、Set 1個分のコンストラクタ `new Set()` の時間を減らすことを狙っています。Setを1個にした替わりに、b の要素の id をSet にaddするときに、それが b の要素のid であることが分かるように、ビット反転した値を add しています。
154
154
 
155
155
 
156
156
 

2

テキスト修正

2019/11/14 14:54

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -88,4 +88,94 @@
88
88
 
89
89
 
90
90
 
91
+ ### 追記 - getUnique11
92
+
93
+
94
+
95
+ 上記の `getUnique10` の改良案を挙げます。ただしこの改良案は、コメントに書いたように、下記
96
+
97
+
98
+
99
+ ```javascript
100
+
101
+ const num = 1000;
102
+
103
+ for (let i = 0; i < num; i++) {
104
+
105
+ const x = i;
106
+
107
+ const y = Math.floor(Math.random() * num);
108
+
109
+ // const id = `${x}:${y}`
110
+
111
+ const id = 1000 * x + y;
112
+
113
+   ・・・
114
+
115
+ ```
116
+
117
+ にて、 `id` を数値として設定することが前提になります。`getUnique11` は以下です。
118
+
119
+
120
+
121
+ ```javascript
122
+
123
+ function getUnique11(a, b) {
124
+
125
+ const set = new Set();
126
+
127
+
128
+
129
+ for (let e of a)
130
+
131
+ set.add(e.id);
132
+
133
+
134
+
135
+ for (let e of b)
136
+
137
+ set.add(~e.id);
138
+
139
+
140
+
141
+ const onlyA = a.filter(e => !set.has(~e.id));
142
+
143
+ const onlyB = b.filter(e => !set.has(e.id));
144
+
145
+
146
+
147
+ return [onlyA, onlyB];
148
+
149
+ }
150
+
151
+ ```
152
+
153
+ `getUnique10` では 2個の Set を使っていましたが、上記の `getUnique11` では、1個で済ませるようにして、Set 1個分のコンストラクタの時間を減らすことを狙っています。Setを1個にした替わりに、b の要素の id をSet にaddするときに、それが b の要素のid であることが分かるように、ビット反転した値を add しています。
154
+
155
+
156
+
157
+ 以下にて、 `getUnique10` と `getUnique11` とを比較できます。
158
+
159
+
160
+
161
+ - **getUnique10 vs getUnique11:** [https://jsfiddle.net/jun68ykt/ajtnd5wm/5/](https://jsfiddle.net/jun68ykt/ajtnd5wm/5/)
162
+
163
+
164
+
165
+ 当方の環境(PC: Macbook Pro(Core i7 2.8GHz), ブラウザ: Chrome バージョン: 78.0.3904.97)では、以下
166
+
167
+
168
+
169
+ ![イメージ説明](09d6a8732bfc89bee7c8ea993573d46a.png)
170
+
171
+
172
+
173
+
174
+
175
+ のように、`getUnique11`の所要時間のほうが、`getUnique10` の所要時間よりも短くなる結果を得ています。
176
+
177
+
178
+
179
+
180
+
91
181
  以上、参考になれば幸いです。

1

テキスト修正

2019/11/14 14:49

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -26,4 +26,66 @@
26
26
 
27
27
 
28
28
 
29
+
30
+
31
+
32
+
33
+
34
+
35
+ ### 追記 - getUnique10
36
+
37
+
38
+
39
+ lodashを使わずに、なるべく高速に処理するコードも考えてみました。以下の `getUnique10` になります。
40
+
41
+
42
+
43
+ ```javascript
44
+
45
+ function getUnique10(a, b) {
46
+
47
+ const [setA, setB] = [new Set(), new Set()];
48
+
49
+
50
+
51
+ for (let e of a)
52
+
53
+ setA.add(e.id);
54
+
55
+
56
+
57
+ for (let e of b)
58
+
59
+ setB.add(e.id);
60
+
61
+
62
+
63
+ const onlyA = a.filter(e => !setB.has(e.id));
64
+
65
+ const onlyB = b.filter(e => !setA.has(e.id));
66
+
67
+
68
+
69
+ return [onlyA, onlyB]
70
+
71
+ }
72
+
73
+ ```
74
+
75
+
76
+
77
+ 上記の `getUnique10` を試すコードを以下の jsFiddle に作成しました。
78
+
79
+
80
+
81
+ - **動作確認用 jsFiddle :** [https://jsfiddle.net/jun68ykt/b501gqpj/1/](https://jsfiddle.net/jun68ykt/b501gqpj/1/)
82
+
83
+
84
+
85
+ これは、コメントからご教示いただきました、 [https://jsfiddle.net/e9a5kvw2/](https://jsfiddle.net/e9a5kvw2/) を Forkして、テスト対象として`getUnique10` を追加したものです。
86
+
87
+
88
+
89
+
90
+
29
91
  以上、参考になれば幸いです。