回答編集履歴

66

テキスト修正

2019/01/21 01:30

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -302,7 +302,7 @@
302
302
 
303
303
 
304
304
 
305
- 今回のご質問では、`map` や `filter` といった高階関数を使って`mergeArrayBasedIDByRevision` を書き直すことがお題ですが、`mergeArrayBasedIDByRevision` 自体もまた、上記のコードのように `reduce`などの高階関数の引数として渡すことができます。
305
+ 今回のご質問では、`map` や `filter` といった高階関数を使って`mergeArrayBasedIDByRevision` を書き直すことがお題ですが、`mergeArrayBasedIDByRevision` 自体もまた、(上記の`reduce`のよう)高階関数の引数として渡すことができます。
306
306
 
307
307
 
308
308
 

65

テキスト修正

2019/01/21 01:30

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -276,7 +276,7 @@
276
276
 
277
277
 
278
278
 
279
- ご質問の要件である2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
279
+ ご質問に提示されてい2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
280
280
 
281
281
 
282
282
 

64

テキスト修正

2019/01/20 12:17

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -276,7 +276,7 @@
276
276
 
277
277
 
278
278
 
279
- ご質問の要件である2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
279
+ ご質問の要件である2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
280
280
 
281
281
 
282
282
 
@@ -284,11 +284,11 @@
284
284
 
285
285
 
286
286
 
287
- を作っておけば __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理は、`mergeArrayBasedIDByRevision` を修正しなくても、以下のようにすれば済みます。
287
+ を作っておけば __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理は、`mergeArrayBasedIDByRevision` を修正しなくても、以下のようにすれば済みます。
288
-
289
-
290
-
288
+
289
+
290
+
291
- ```
291
+ ```javascript
292
292
 
293
293
  const result = [ar1, ar2, ... arN].reduce(mergeArrayBasedIDByRevision);
294
294
 
@@ -296,11 +296,13 @@
296
296
 
297
297
  - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/h6ob920e/7/](https://jsfiddle.net/jun68ykt/h6ob920e/7/)
298
298
 
299
-   
300
-
301
-
302
-
299
+
300
+
301
+    
302
+
303
+
304
+
303
- 今回のご質問では、`map` や `filter` といった高階関数を使って`mergeArrayBasedIDByRevision` を書き直すというのがお題ですが、`mergeArrayBasedIDByRevision` 自体もまた、上記のコードのようにreduceなどの高階関数の引数として渡すことができます。
305
+ 今回のご質問では、`map` や `filter` といった高階関数を使って`mergeArrayBasedIDByRevision` を書き直すとがお題ですが、`mergeArrayBasedIDByRevision` 自体もまた、上記のコードのように `reduce`などの高階関数の引数として渡すことができます。
304
306
 
305
307
 
306
308
 

63

テキスト修正

2019/01/20 11:37

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -364,4 +364,4 @@
364
364
 
365
365
 
366
366
 
367
- 実用的には、結果から見る限り、コード1がお勧めということになりますが、回答に載せているままだと、若干読みにくいコードかと思われますので、お好みで、適宜、中間の変数を追加したり、インデントを変えるなどリファクタリングして頂ければと思います。
367
+ 実用的には、結果から見る限り、コード1がお勧めということになりますが、回答に載せているコードのままだと、若干読みにくいコードかと思われますので、一時的な変数を追加したり、インデントを修正するなど、適宜リファクタリングして頂ければと思います。

62

テキスト修正

2019/01/20 02:41

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -276,7 +276,7 @@
276
276
 
277
277
 
278
278
 
279
- ご質問の要件、2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
279
+ ご質問の要件である、2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
280
280
 
281
281
 
282
282
 
@@ -284,7 +284,7 @@
284
284
 
285
285
 
286
286
 
287
- を作ることですが、これを作っておけば __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理は、以下のようにすれば済みます。
287
+ を作っておけば __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理は、`mergeArrayBasedIDByRevision` を修正しなくても、以下のようにすれば済みます。
288
288
 
289
289
 
290
290
 

61

テキスト修正

2019/01/20 00:30

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -300,7 +300,7 @@
300
300
 
301
301
 
302
302
 
303
- 今回のご質問では、`map` や `filter` といった高階関数を使って`mergeArrayBasedIDByRevision` を書き直すというのがお題ですが、そのようにして作った`mergeArrayBasedIDByRevision` もまた、上記のコードのようにreduceなどの高階関数の引数として渡すことができます。
303
+ 今回のご質問では、`map` や `filter` といった高階関数を使って`mergeArrayBasedIDByRevision` を書き直すというのがお題ですが、`mergeArrayBasedIDByRevision` 自体もまた、上記のコードのようにreduceなどの高階関数の引数として渡すことができます。
304
304
 
305
305
 
306
306
 

60

テキスト修正

2019/01/19 22:51

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
 
24
24
 
25
- 上記2点により、コード1から6までのいずれも、セミコロン `;` は `return`文の末尾にしか使われていないものになっています。
25
+ 上記2点により、コード1から6までのいずれも、セミコロン `;` は `return`文の末尾にしか使われていないものになっています。ただしコードが短くなっただけで、効率が悪く処理時間が長くかかってしまうような例も挙げています。
26
26
 
27
27
 
28
28
 

59

テキスト修正

2019/01/19 15:25

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -320,7 +320,7 @@
320
320
 
321
321
 
322
322
 
323
- - 配列要素の各プロパティは以下
323
+ - 配列要素の各プロパティは以下のとおり:
324
324
 
325
325
  `id` : `/^[a-z][0-9]{2}$/` という形式の文字列(従って2600通り)をランダム生成(例: `a00`, `h56` )
326
326
 

58

テキスト修正

2019/01/19 14:32

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -300,7 +300,7 @@
300
300
 
301
301
 
302
302
 
303
- 今回のご質問では、`map` や `filter` といった高階関数を使って`mergeArrayBasedIDByRevision` を書き直すというのがお題ですが、そのようにして作った`mergeArrayBasedIDByRevision` もまた、上記のコードのようにreduceなどの高階関数の引数として渡ます。
303
+ 今回のご質問では、`map` や `filter` といった高階関数を使って`mergeArrayBasedIDByRevision` を書き直すというのがお題ですが、そのようにして作った`mergeArrayBasedIDByRevision` もまた、上記のコードのようにreduceなどの高階関数の引数として渡すことができます。
304
304
 
305
305
 
306
306
 

57

テキスト修正

2019/01/19 14:28

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -312,7 +312,25 @@
312
312
 
313
313
 
314
314
 
315
+ コード1から6までの簡単な性能比較を行いました。方法は
316
+
317
+
318
+
319
+ - 2つの配列 `ar1` と `ar2` をともに長さ25万の配列(つまり`ar1.concat(ar2)` の長さは50万)として用意
320
+
321
+
322
+
323
+ - 配列要素の各プロパティは以下
324
+
325
+ `id` : `/^[a-z][0-9]{2}$/` という形式の文字列(従って2600通り)をランダム生成(例: `a00`, `h56` )
326
+
327
+ `rev` : 0以上 125000以下の整数をランダム生成
328
+
329
+ `val` : 0
330
+
331
+
332
+
315
- コード1から6まで簡単性能比較を行いました。方法は2つの配列 `ar1` と `ar2` をともに長さ25万の配列(つまり、 `ar1.concat(ar2)` は長さ50万)として用意し、各コードの`mergeArrayBasedIDByRevision(ar1, ar2)`を実行して、その所要時間を計測しました。その結果が以下です。
333
+ 上記ような `ar1` と `ar2` を用意し、各コードの`mergeArrayBasedIDByRevision(ar1, ar2)`を実行して、その所要時間を計測しました。その結果が以下です。
316
334
 
317
335
 
318
336
 

56

テキスト修正

2019/01/19 14:16

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -6,11 +6,11 @@
6
6
 
7
7
 
8
8
 
9
- - `for`によるループを使うかわりに `Array` のメソッドの `map` や `filter` といった、関数を引数として受け取れるものすなわち[高階関数](https://ja.wikipedia.org/wiki/%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0)を使ったコードにしたい
9
+ - `for`によるループを使うかわりに `Array` のメソッドの `map` や `filter` といった、関数を引数として受け取れるものすなわち[高階関数](https://ja.wikipedia.org/wiki/%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0) を使ったコードにしたい
10
-
11
-
12
-
10
+
11
+
12
+
13
- というものと把握しました。この回答では、そういった関数の使用事例となるように、コード1から6までの複数のコードを回答します。これらは、短いコードで済ませることを主眼においているので、
13
+ というものと拝察しました。この回答では、そういった関数の使用事例となるように、コード1から6までの複数のコードを回答します。これらは、短いコードで済ませることを主眼においているので、
14
14
 
15
15
 
16
16
 

55

テキスト修正

2019/01/19 13:52

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -274,7 +274,9 @@
274
274
 
275
275
  任意の __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理について補足しておきます。
276
276
 
277
+
278
+
277
- 2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
279
+ ご質問の要件は、2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
278
280
 
279
281
 
280
282
 
@@ -282,7 +284,7 @@
282
284
 
283
285
 
284
286
 
285
- を作っておけば__N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理は、以下のようにすれば済みます。
287
+ を作ることですが、これを作っておけば __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理は、以下のようにすれば済みます。
286
288
 
287
289
 
288
290
 

54

テキスト修正

2019/01/19 13:50

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -122,6 +122,10 @@
122
122
 
123
123
 
124
124
 
125
+ また、`ary` の中にある、ある特定idの要素を探すのに `find`を使っていますが、`find` だと先頭から順に探していくので、これも効率悪いです。
126
+
127
+
128
+
125
129
  ### コード3
126
130
 
127
131
 

53

テキスト修正

2019/01/19 13:46

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -294,6 +294,10 @@
294
294
 
295
295
 
296
296
 
297
+ 今回のご質問では、`map` や `filter` といった高階関数を使って`mergeArrayBasedIDByRevision` を書き直すというのがお題ですが、そのようにして作った`mergeArrayBasedIDByRevision` もまた、上記のコードのようにreduceなどの高階関数の引数として渡せます。
298
+
299
+
300
+
297
301
  回答のコード1とコード2でも使いましたが、[reduce](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)を使いこなせると色々な場面で重宝します。
298
302
 
299
303
 

52

テキスト修正

2019/01/19 13:42

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
 
13
- というものと把握しました。この回答では、そういった関数の使用事例となるように、複数のコードを回答します。これらは、コード1から6まであり、短いコードで済ませることを主眼においているので、
13
+ というものと把握しました。この回答では、そういった関数の使用事例となるように、コード1から6までの複数のコードを回答します。これらは、短いコードで済ませることを主眼においているので、
14
14
 
15
15
 
16
16
 
@@ -30,15 +30,15 @@
30
30
 
31
31
 
32
32
 
33
- (1) 2つの配列の効率的な連結方法についてはご質問の本題ではないと思われたので、ご質問のコードでお使いになっている `concat` をそのまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。
34
-
35
-
36
-
37
- (2) `mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意の __N__ 個にすることはご質問の主旨から逸脱すると考えたため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました。
38
-
39
-
40
-
41
- (3) 簡単な性能比較を補足4に追記しました。
33
+ - 2つの配列の効率的な連結方法についてはご質問の本題ではないと思われたので、ご質問のコードでお使いになっている `concat` をそのまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。
34
+
35
+  
36
+
37
+ - `mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意の __N__ 個にすることはご質問の主旨から逸脱すると考えたため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました。
38
+
39
+   
40
+
41
+ - 簡単な性能比較を補足4に追記しました。
42
42
 
43
43
 
44
44
 

51

テキスト修正

2019/01/19 13:20

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -2,25 +2,15 @@
2
2
 
3
3
 
4
4
 
5
- ご質問に
6
-
7
-
8
-
9
- > そこでforを使った関数を作成しましたが、どうも見辛くスマートさに欠けるため
10
-
11
- mapやfilterなどのイテレーター的な関数を使って書き直せないものかと思っています。
12
-
13
-
14
-
15
- とあったので、`for`によるループを使うかわりに `map` や `filter` といった( __"イテレーター的な" __とおっしゃるところの)関数を使ったコードをお知りになりたいものと思いました。この回答では、そのような関数の使用事例となるように、複数のコードを回答します。(コード1から6まであります。)
16
-
17
-
18
-
19
- なお以下回答コードでは、
5
+ ご質問趣旨としては、
6
+
7
+
8
+
20
-
9
+ - `for`によるループを使うかわりに `Array` のメソッドの `map` や `filter` といった、関数を引数として受け取れるもの(すなわち[高階関数](https://ja.wikipedia.org/wiki/%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0))を使ったコードにしたい
21
-
22
-
10
+
11
+
12
+
23
- (1) 短いコードで済ませることを主眼においているので、
13
+ というものと把握しました。この回答では、そういった関数の使用事例となるように、複数のコードを回答します。これらは、コード1から6まであり、短いコードで済ませることを主眼においているので、
24
14
 
25
15
 
26
16
 
@@ -32,15 +22,23 @@
32
22
 
33
23
 
34
24
 
35
- (2) つの配列の効率的な連結方法ついてはご質問の本題ではないと思われたのでご質問のコードでお使になっている `concat` をそまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません
36
-
37
-
38
-
39
- (3) `mergeArrayBasedIDByRevision()`の引数 `array1` と `array2` の2つか、任意の __N__ 個にすることはご質問の主旨ら逸脱すると考えたた対応してせんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応ることは簡単にできることを補足3に追記しました
40
-
41
-
42
-
43
- (4) 簡単性能比較補足4に追記しました
25
+ 上記より、コード1から6まずれも、セミコロン `;` は `return`末尾にしか使われていないものになっています。
26
+
27
+
28
+
29
+ また、以下らか補足しておきます。
30
+
31
+
32
+
33
+ (1) 2つの配列の効率的連結方法についてはご質問の本題ではないと思われたので、ご質問のコードでお使いになっている `concat` そのまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもせん
34
+
35
+
36
+
37
+ (2) `mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意の __N__ 個にすることはご質問の主旨から逸脱すると考えたため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました。
38
+
39
+
40
+
41
+ (3) 簡単な性能比較を補足4に追記しました。
44
42
 
45
43
 
46
44
 

50

テキスト修正

2019/01/19 13:11

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -334,7 +334,7 @@
334
334
 
335
335
 
336
336
 
337
- 結果をみると、コード1の性能が良いです。注目すべき差としては、まず、コード1とコード2の結果の差です。コード1で使っていたMapの働きを、コード2ではfind と filter でやってみたわけですが、これだけの差になってしまいました。それと、コード3が5分経っても終わらなかったのが、コード6に修正したことで5秒程度で正常終了するようになりました。コード4 については、 `ar1`, `ar2` ともに 5万件ずつの計10万件だと、約0.2秒かかって正常終了しました。
337
+ 結果をみると、コード1の性能が良いです。注目すべき差としては、まず、コード1とコード2の結果の差です。コード1で使っていたMapの働きを、コード2ではfind と filter でやってみたわけですが、これだけの差になってしまいました。それと、コード3が5分経っても終わらなかったのが、コード6に修正したことで5秒程度で正常終了するようになりました。コード4 については、上記の表には書いてませんが `ar1`, `ar2` ともに 5万件ずつの計10万件だと、約0.2秒かかって正常終了しました。
338
338
 
339
339
 
340
340
 

49

テキスト修正

2019/01/19 07:39

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
 
15
- とあったので、この問題の処理のために最適化されたアルゴリズムというよりも、`for`を使うかわりに map やfilter といった( __"イテレーター的な" __とおっしゃるところの)便利な関数を使ったやり方をお求めかと思われましたので、以下、そのようないくつかの関数の使用例となるように複数のコードを回答します。(コード1から6まであります。)
15
+ とあったので、`for`によるループを使うかわりに `map` `filter` といった( __"イテレーター的な" __とおっしゃるところの)関数を使ったコードをお知りになりたいものと思ました。こ回答、そのような関数の使用例となるように複数のコードを回答します。(コード1から6まであります。)
16
16
 
17
17
 
18
18
 

48

テキスト修正

2019/01/19 07:20

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -40,6 +40,8 @@
40
40
 
41
41
 
42
42
 
43
+ (4) 簡単な性能比較を補足4に追記しました。
44
+
43
45
 
44
46
 
45
47
  ### コード1

47

テキスト修正

2019/01/19 01:57

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -332,7 +332,7 @@
332
332
 
333
333
 
334
334
 
335
- 結果をみると、コード1の性能が良いです。注目すべき差としては、まず、コード1とコード2の結果の差です。コード1で使っていたMapの働きを、コード2ではfind と filter でやってみたわけですが、これだけの差になってしまいました。それと、コード3が5分経っても終わらなかったのが、コード6に修正したことで5秒程度で正常終了するようになりました。コード4 については、 `ar1`, `ar2` ともに 5万件ずつの計10万件だと、約2秒かかって正常終了しました。
335
+ 結果をみると、コード1の性能が良いです。注目すべき差としては、まず、コード1とコード2の結果の差です。コード1で使っていたMapの働きを、コード2ではfind と filter でやってみたわけですが、これだけの差になってしまいました。それと、コード3が5分経っても終わらなかったのが、コード6に修正したことで5秒程度で正常終了するようになりました。コード4 については、 `ar1`, `ar2` ともに 5万件ずつの計10万件だと、約0.2秒かかって正常終了しました。
336
336
 
337
337
 
338
338
 

46

テキスト修正

2019/01/19 01:50

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -295,3 +295,45 @@
295
295
 
296
296
 
297
297
  回答のコード1とコード2でも使いましたが、[reduce](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)を使いこなせると色々な場面で重宝します。
298
+
299
+
300
+
301
+ ### 補足4
302
+
303
+
304
+
305
+ コード1から6までの簡単な性能比較を行いました。方法は2つの配列 `ar1` と `ar2` をともに長さ25万の配列(つまり、 `ar1.concat(ar2)` は長さ50万)として用意し、各コードの`mergeArrayBasedIDByRevision(ar1, ar2)`を実行して、その所要時間を計測しました。その結果が以下です。
306
+
307
+
308
+
309
+ |No.|結果|
310
+
311
+ |:--:|:--:|
312
+
313
+ |コード1|0.052 秒|
314
+
315
+ |コード2|10.767 秒|
316
+
317
+ |コード3|5分経過しても終わらず|
318
+
319
+ |コード4|エラー終了|
320
+
321
+ |コード5|0.63 秒|
322
+
323
+ |コード6|5.14 秒|
324
+
325
+
326
+
327
+
328
+
329
+ - 使用PC: MacBookPro (CPU:core i7 2.7GHz, メモリ16GB)
330
+
331
+ - コード4のエラー原因: Maximum call stack size exceeded
332
+
333
+
334
+
335
+ 結果をみると、コード1の性能が良いです。注目すべき差としては、まず、コード1とコード2の結果の差です。コード1で使っていたMapの働きを、コード2ではfind と filter でやってみたわけですが、これだけの差になってしまいました。それと、コード3が5分経っても終わらなかったのが、コード6に修正したことで5秒程度で正常終了するようになりました。コード4 については、 `ar1`, `ar2` ともに 5万件ずつの計10万件だと、約2秒かかって正常終了しました。
336
+
337
+
338
+
339
+ 実用的には、結果から見る限り、コード1がお勧めということになりますが、回答に載せているもののままだと、若干読みにくいコードかと思われますので、お好みで、適宜、中間の変数を追加したり、インデントを変えるなどのリファクタリングして頂ければと思います。

45

テキスト修正

2019/01/19 01:47

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -20,278 +20,278 @@
20
20
 
21
21
 
22
22
 
23
+ (1) 短いコードで済ませることを主眼においているので、
24
+
25
+
26
+
23
- - 短いコードで済ませることを主眼においているので、関数 `mergeArrayBasedIDByRevision` 本体の最初の行に`return` を書いて、`return` する対象の中にロジックを(あえて)詰め込みました。
27
+ - 関数 `mergeArrayBasedIDByRevision` 本体の最初の行に`return` を書いて、`return` する対象の中にロジックを(あえて)詰め込みました。
24
28
 
25
29
   
26
30
 
27
- - 同じく、短いコードで済ませることを主眼においているので、アロー関数 `=>` を使う場合に、アローの先にある関数本体の記述に、`return` を使わないで済ませるようなコードを目指しました。
31
+ - アロー関数 `=>` を使うに、アローの先にある関数本体の記述に、`return` を使わないで済ませるようしました。
32
+
33
+
34
+
35
+ (2) 2つの配列の効率的な連結方法についてはご質問の本題ではないと思われたので、ご質問のコードでお使いになっている `concat` をそのまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。
36
+
37
+
38
+
39
+ (3) `mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意の __N__ 個にすることはご質問の主旨から逸脱すると考えたため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました。
40
+
41
+
42
+
43
+
44
+
45
+ ### コード1
46
+
47
+
48
+
49
+ reduce, Map, スプレッド構文を使います。
50
+
51
+
52
+
53
+ ```javascript
54
+
55
+ function mergeArrayBasedIDByRevision(array1, array2) {
56
+
57
+ return [...
58
+
59
+ array1
60
+
61
+ .concat(array2)
62
+
63
+ .reduce(
64
+
65
+ (map, e) =>
66
+
67
+ (map.get(e.id) || {}).rev >= e.rev
68
+
69
+ ? map
70
+
71
+ : map.set(e.id, e)
72
+
73
+ , new Map())
74
+
75
+ .values()
76
+
77
+ ];
78
+
79
+ }
80
+
81
+ ```
82
+
83
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/suL7tx3k/12/](https://jsfiddle.net/jun68ykt/suL7tx3k/12/)
84
+
85
+
86
+
87
+
88
+
89
+ ### コード2
90
+
91
+
92
+
93
+ Map を使わず find と filter を使ってみたコードです。
94
+
95
+ ```javascript
96
+
97
+ function mergeArrayBasedIDByRevision(array1, array2) {
98
+
99
+ return array1.concat(array2).reduce(
100
+
101
+ (ary, e) =>
102
+
103
+ (ary.find(e2 => e2.id === e.id) || {}).rev >= e.rev
104
+
105
+ ? ary
106
+
107
+ : [...ary.filter(e3 => e3.id !== e.id), e]
108
+
109
+ , []
110
+
111
+ );
112
+
113
+ }
114
+
115
+ ```
116
+
117
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/b9kseywr/10/](https://jsfiddle.net/jun68ykt/b9kseywr/10/)
118
+
119
+
120
+
121
+ ただし、`e.id`と同じidの要素が除去された配列を作るのに、`ary.filter(e3 => e3.id !== e.id)` としている所が無駄です。なぜかというと`ary.filter` とすると `ary`の全要素を走査してしまいますが、`ary`の中には同じ`id`の要素は最大でも1個しかないからです。
122
+
123
+
124
+
125
+ ### コード3
126
+
127
+
128
+
129
+ ar1 と ar2 を結合して、**idの昇順+revの降順**でソートし、ソート結果から各idのrevが最大のものだけをピックアップします。
130
+
131
+ ```javascript
132
+
133
+ function mergeArrayBasedIDByRevision(array1, array2) {
134
+
135
+ return array1.concat(array2)
136
+
137
+ .sort((e1, e2) => e1.id.localeCompare(e2.id) || e2.rev - e1.rev)
138
+
139
+ .filter((e, i, ary) => i === ary.findIndex(e3 => e3.id === e.id));
140
+
141
+ }
142
+
143
+ ```
144
+
145
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/zLodvq7c/3/](https://jsfiddle.net/jun68ykt/zLodvq7c/3/)
146
+
147
+
148
+
149
+ ただし、要素すべてについて`ary.findIndex(e3 => e3.id === e.id)`を毎回やるので無駄が多いです。
150
+
151
+
152
+
153
+ ### コード4,5
154
+
155
+
156
+
157
+ array1 と array2を結合した配列を revの**昇順**でソートし、map で各要素を適切に変形したうえで、Object.assign ないし Mapのコンストラクターに渡します。
158
+
159
+
160
+
161
+ #### コード4
162
+
163
+ ```javascript
164
+
165
+ function mergeArrayBasedIDByRevision(array1, array2) {
166
+
167
+ return Object.values(
168
+
169
+ Object.assign({},
170
+
171
+ ...array1.concat(array2)
172
+
173
+ .sort((e1, e2) => e1.rev - e2.rev)
174
+
175
+ .map(e => ({[e.id]: e}))
176
+
177
+ )
178
+
179
+ );
180
+
181
+ }
182
+
183
+ ```
184
+
185
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/13/](https://jsfiddle.net/jun68ykt/jf1283mg/13/)
186
+
187
+
188
+
189
+ #### コード5
190
+
191
+ ```javascript
192
+
193
+ function mergeArrayBasedIDByRevision(array1, array2) {
194
+
195
+ return [...
196
+
197
+ new Map(
198
+
199
+ array1.concat(array2)
200
+
201
+ .sort((e1, e2) => e1.rev - e2.rev)
202
+
203
+ .map(e => [e.id, e])
204
+
205
+ ).values()
206
+
207
+ ];
208
+
209
+ }
210
+
211
+ ```
212
+
213
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/a4hpgLtn/3/](https://jsfiddle.net/jun68ykt/a4hpgLtn/3/)
214
+
215
+
216
+
217
+
218
+
219
+ ### コード6 (コード3の修正版)
220
+
221
+
222
+
223
+ 先に挙げたコード3の問題点だった、filter の判定 `i === ary.findIndex(e3 => e3.id === e.id)` を修正しました。
224
+
225
+
226
+
227
+ ```javascript
228
+
229
+ function mergeArrayBasedIDByRevision(array1, array2) {
230
+
231
+ return array1.concat(array2)
232
+
233
+ .sort((e1, e2) => e1.id.localeCompare(e2.id) || e2.rev - e1.rev)
234
+
235
+ .filter((e, i, ary) => i === 0 || e.id !== ary[i-1].id);
236
+
237
+ }
238
+
239
+ ```
240
+
241
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/h6ob920e/1/](https://jsfiddle.net/jun68ykt/h6ob920e/1/)
242
+
243
+
244
+
245
+
246
+
247
+
248
+
249
+ ### 補足1
250
+
251
+
252
+
253
+ このご質問の場合、idをキーとする何らかのマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の6つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由するのが適切なときに、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率なロジックになってしまっていることが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
254
+
255
+
256
+
257
+
258
+
259
+ ### 補足2
260
+
261
+
262
+
263
+ コード3の問題点を修正したコード6を追記しました。この修正によって、idをキーとするMapやプレーンオブジェクトを経由しないで配列のままでどうにかする方法の一案として、そこそこ実用に耐えうるものになったのではと思います。
264
+
265
+    
266
+
267
+ ### 補足3
268
+
269
+
270
+
271
+ 任意の __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理について補足しておきます。
272
+
273
+ 2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
274
+
275
+
276
+
277
+ `function mergeArrayBasedIDByRevision(array1, array2)`
278
+
279
+
280
+
281
+ を作っておけば、__N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理は、以下のようにすれば済みます。
282
+
283
+
284
+
285
+ ```
286
+
287
+ const result = [ar1, ar2, ... arN].reduce(mergeArrayBasedIDByRevision);
288
+
289
+ ```
290
+
291
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/h6ob920e/7/](https://jsfiddle.net/jun68ykt/h6ob920e/7/)
28
292
 
29
293
    
30
294
 
31
- - 2つの配列の効率的な連結方法についてはご質問の本題ではないと思われたので、ご質問のコードでお使いになっている `concat` をそのまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。
32
-
33
-
34
-
35
- また、
36
-
37
-
38
-
39
- - `mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意の __N__ 個にすることはご質問の主旨から逸脱すると考えたため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました。
40
-
41
-
42
-
43
-
44
-
45
- ### コード1
46
-
47
-
48
-
49
- reduce, Map, スプレッド構文を使います。
50
-
51
-
52
-
53
- ```javascript
54
-
55
- function mergeArrayBasedIDByRevision(array1, array2) {
56
-
57
- return [...
58
-
59
- array1
60
-
61
- .concat(array2)
62
-
63
- .reduce(
64
-
65
- (map, e) =>
66
-
67
- (map.get(e.id) || {}).rev >= e.rev
68
-
69
- ? map
70
-
71
- : map.set(e.id, e)
72
-
73
- , new Map())
74
-
75
- .values()
76
-
77
- ];
78
-
79
- }
80
-
81
- ```
82
-
83
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/suL7tx3k/12/](https://jsfiddle.net/jun68ykt/suL7tx3k/12/)
84
-
85
-
86
-
87
-
88
-
89
- ### コード2
90
-
91
-
92
-
93
- Map を使わず find と filter を使ってみたコードです。
94
-
95
- ```javascript
96
-
97
- function mergeArrayBasedIDByRevision(array1, array2) {
98
-
99
- return array1.concat(array2).reduce(
100
-
101
- (ary, e) =>
102
-
103
- (ary.find(e2 => e2.id === e.id) || {}).rev >= e.rev
104
-
105
- ? ary
106
-
107
- : [...ary.filter(e3 => e3.id !== e.id), e]
108
-
109
- , []
110
-
111
- );
112
-
113
- }
114
-
115
- ```
116
-
117
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/b9kseywr/10/](https://jsfiddle.net/jun68ykt/b9kseywr/10/)
118
-
119
-
120
-
121
- ただし、`e.id`と同じidの要素が除去された配列を作るのに、`ary.filter(e3 => e3.id !== e.id)` としている所が無駄です。なぜかというと`ary.filter` とすると `ary`の全要素を走査してしまいますが、`ary`の中には同じ`id`の要素は最大でも1個しかないからです。
122
-
123
-
124
-
125
- ### コード3
126
-
127
-
128
-
129
- ar1 と ar2 を結合して、**idの昇順+revの降順**でソートし、ソート結果から各idのrevが最大のものだけをピックアップします。
130
-
131
- ```javascript
132
-
133
- function mergeArrayBasedIDByRevision(array1, array2) {
134
-
135
- return array1.concat(array2)
136
-
137
- .sort((e1, e2) => e1.id.localeCompare(e2.id) || e2.rev - e1.rev)
138
-
139
- .filter((e, i, ary) => i === ary.findIndex(e3 => e3.id === e.id));
140
-
141
- }
142
-
143
- ```
144
-
145
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/zLodvq7c/3/](https://jsfiddle.net/jun68ykt/zLodvq7c/3/)
146
-
147
-
148
-
149
- ただし、要素すべてについて`ary.findIndex(e3 => e3.id === e.id)`を毎回やるので無駄が多いです。
150
-
151
-
152
-
153
- ### コード4,5
154
-
155
-
156
-
157
- array1 と array2を結合した配列を revの**昇順**でソートし、map で各要素を適切に変形したうえで、Object.assign ないし Mapのコンストラクターに渡します。
158
-
159
-
160
-
161
- #### コード4
162
-
163
- ```javascript
164
-
165
- function mergeArrayBasedIDByRevision(array1, array2) {
166
-
167
- return Object.values(
168
-
169
- Object.assign({},
170
-
171
- ...array1.concat(array2)
172
-
173
- .sort((e1, e2) => e1.rev - e2.rev)
174
-
175
- .map(e => ({[e.id]: e}))
176
-
177
- )
178
-
179
- );
180
-
181
- }
182
-
183
- ```
184
-
185
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/13/](https://jsfiddle.net/jun68ykt/jf1283mg/13/)
186
-
187
-
188
-
189
- #### コード5
190
-
191
- ```javascript
192
-
193
- function mergeArrayBasedIDByRevision(array1, array2) {
194
-
195
- return [...
196
-
197
- new Map(
198
-
199
- array1.concat(array2)
200
-
201
- .sort((e1, e2) => e1.rev - e2.rev)
202
-
203
- .map(e => [e.id, e])
204
-
205
- ).values()
206
-
207
- ];
208
-
209
- }
210
-
211
- ```
212
-
213
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/a4hpgLtn/3/](https://jsfiddle.net/jun68ykt/a4hpgLtn/3/)
214
-
215
-
216
-
217
-
218
-
219
- ### コード6 (コード3の修正版)
220
-
221
-
222
-
223
- 先に挙げたコード3の問題点だった、filter の判定 `i === ary.findIndex(e3 => e3.id === e.id)` を修正しました。
224
-
225
-
226
-
227
- ```javascript
228
-
229
- function mergeArrayBasedIDByRevision(array1, array2) {
230
-
231
- return array1.concat(array2)
232
-
233
- .sort((e1, e2) => e1.id.localeCompare(e2.id) || e2.rev - e1.rev)
234
-
235
- .filter((e, i, ary) => i === 0 || e.id !== ary[i-1].id);
236
-
237
- }
238
-
239
- ```
240
-
241
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/h6ob920e/1/](https://jsfiddle.net/jun68ykt/h6ob920e/1/)
242
-
243
-
244
-
245
-
246
-
247
-
248
-
249
- ### 補足1
250
-
251
-
252
-
253
- このご質問の場合、idをキーとする何らかのマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の6つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由するのが適切なときに、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率なロジックになってしまっていることが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
254
-
255
-
256
-
257
-
258
-
259
- ### 補足2
260
-
261
-
262
-
263
- コード3の問題点を修正したコード6を追記しました。この修正によって、idをキーとするMapやプレーンオブジェクトを経由しないで配列のままでどうにかする方法の一案として、そこそこ実用に耐えうるものになったのではと思います。
264
-
265
-    
266
-
267
- ### 補足3
268
-
269
-
270
-
271
- 任意の __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理について補足しておきます。
272
-
273
- 2つの配列 `array1`, `array2`を引数として受け取り、これらをマージした配列を返す関数
274
-
275
-
276
-
277
- `function mergeArrayBasedIDByRevision(array1, array2)`
278
-
279
-
280
-
281
- を作っておけば、__N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理は、以下のようにすれば済みます。
282
-
283
-
284
-
285
- ```
286
-
287
- const result = [ar1, ar2, ... arN].reduce(mergeArrayBasedIDByRevision);
288
-
289
- ```
290
-
291
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/h6ob920e/7/](https://jsfiddle.net/jun68ykt/h6ob920e/7/)
292
-
293
-   
294
-
295
295
 
296
296
 
297
297
  回答のコード1とコード2でも使いましたが、[reduce](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)を使いこなせると色々な場面で重宝します。

44

テキスト修正

2019/01/17 17:54

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
 
15
- とあったので、この問題の処理のために最適化されたアルゴリズムというよりも、`for`を使うかわりに map やfilter といった、( __"イテレーター的な" __とおっしゃるところの)便利な関数を使ったやり方をお求めかと思われましたので、以下、そのような関数の使用例となるように複数のコードを回答します。
15
+ とあったので、この問題の処理のために最適化されたアルゴリズムというよりも、`for`を使うかわりに map やfilter といった、( __"イテレーター的な" __とおっしゃるところの)便利な関数を使ったやり方をお求めかと思われましたので、以下、そのようないくつかの関数の使用例となるように複数のコードを回答します。(コード1から6まであります。)
16
16
 
17
17
 
18
18
 
@@ -20,13 +20,13 @@
20
20
 
21
21
 
22
22
 
23
- - 短いコードで済ませることを主眼においているので、関数 `mergeArrayBasedIDByRevision` 本体の最初の行に`return` を書いて、`return` する対象の中にロジックを詰め込みました。
23
+ - 短いコードで済ませることを主眼においているので、関数 `mergeArrayBasedIDByRevision` 本体の最初の行に`return` を書いて、`return` する対象の中にロジックを(あえて)詰め込みました。
24
-
25
-
24
+
25
+  
26
26
 
27
27
  - 同じく、短いコードで済ませることを主眼においているので、アロー関数 `=>` を使う場合に、アローの先にある関数本体の記述に、`return` を使わないで済ませるようなコードを目指しました。
28
28
 
29
-
29
+   
30
30
 
31
31
  - 2つの配列の効率的な連結方法についてはご質問の本題ではないと思われたので、ご質問のコードでお使いになっている `concat` をそのまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。
32
32
 

43

テキスト修正

2019/01/17 17:47

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -20,6 +20,14 @@
20
20
 
21
21
 
22
22
 
23
+ - 短いコードで済ませることを主眼においているので、関数 `mergeArrayBasedIDByRevision` 本体の最初の行に`return` を書いて、`return` する対象の中にロジックを詰め込みました。
24
+
25
+
26
+
27
+ - 同じく、短いコードで済ませることを主眼においているので、アロー関数 `=>` を使う場合に、アローの先にある関数本体の記述に、`return` を使わないで済ませるようなコードを目指しました。
28
+
29
+
30
+
23
31
  - 2つの配列の効率的な連結方法についてはご質問の本題ではないと思われたので、ご質問のコードでお使いになっている `concat` をそのまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。
24
32
 
25
33
 

42

テキスト修正

2019/01/17 12:09

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -262,7 +262,7 @@
262
262
 
263
263
  任意の __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理について補足しておきます。
264
264
 
265
- 2つの配列 `array1`, `array2`を引数として受け取り、マージされた配列を返す関数
265
+ 2つの配列 `array1`, `array2`を引数として受け取り、これらをマージた配列を返す関数
266
266
 
267
267
 
268
268
 

41

テキスト修正

2019/01/16 07:13

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -262,7 +262,7 @@
262
262
 
263
263
  任意の __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理について補足しておきます。
264
264
 
265
- ご質問にあるような、2つの配列 `array1`, `array2`を引数として受け取
265
+ 2つの配列 `array1`, `array2`を引数として受け取り、マージされた配列を返す関数
266
266
 
267
267
 
268
268
 

40

テキスト修正

2019/01/16 06:55

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -28,7 +28,7 @@
28
28
 
29
29
 
30
30
 
31
- - `mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意の __N__ 個にすることはご質問の要件から逸脱すると考えたため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました。
31
+ - `mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意の __N__ 個にすることはご質問の主旨から逸脱すると考えたため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました。
32
32
 
33
33
 
34
34
 

39

テキスト修正

2019/01/16 06:02

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -238,7 +238,7 @@
238
238
 
239
239
 
240
240
 
241
- ### 補足
241
+ ### 補足1
242
242
 
243
243
 
244
244
 

38

テキスト修正

2019/01/16 05:42

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -16,11 +16,19 @@
16
16
 
17
17
 
18
18
 
19
- - なお以下の回答コードでは、2つの配列の連結についてはご質問の本題ではないと思われたので、ご質問のコードでお使いになっている `concat` をそのまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。
20
-
21
-     
22
-
23
- - また、`mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意 __N__ 個することはご質問の要件から逸脱する考えため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました
19
+ なお以下の回答コードでは、
20
+
21
+
22
+
23
+ - 2つの配列の効率的な連結方法ついてはご質問の本題ではない思われので、ご質問のコードでお使いになっている `concat` をそのま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもせん
24
+
25
+
26
+
27
+ また、
28
+
29
+
30
+
31
+ - `mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意の __N__ 個にすることはご質問の要件から逸脱すると考えたため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました。
24
32
 
25
33
 
26
34
 

37

テキスト修正

2019/01/16 05:26

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -12,11 +12,17 @@
12
12
 
13
13
 
14
14
 
15
- とあったので、この問題の処理のために最適化されたアルゴリズムというよりも、`for`を使うかわりに map やfilter といった、( __"イテレーター的な" __とおっしゃるところの)便利な関数を使ったやり方をお求めかと思われましたので、以下、そのような関数の例となるように複数のコードを回答します。
16
-
17
-
18
-
19
- (※なお以下の回答コードでは、2つの配列の連結についてはご質問の本題ではないので、ご質問のコードでお使いになっている concat をそのまま使いますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。また、関数の引数を array1 と array2 の2つから、任意の個数にすることもご質問の要件にはなかったので未対応です。)
15
+ とあったので、この問題の処理のために最適化されたアルゴリズムというよりも、`for`を使うかわりに map やfilter といった、( __"イテレーター的な" __とおっしゃるところの)便利な関数を使ったやり方をお求めかと思われましたので、以下、そのような関数の使用例となるように複数のコードを回答します。
16
+
17
+
18
+
19
+ - なお以下の回答コードでは、2つの配列の連結についてはご質問の本題ではないと思われたので、ご質問のコードでお使いになっている `concat` をそのまま使っていますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。
20
+
21
+     
22
+
23
+ - また、`mergeArrayBasedIDByRevision()`の引数を `array1` と `array2` の2つから、任意の __N__ 個にすることはご質問の要件から逸脱すると考えたため対応していませんが、`mergeArrayBasedIDByRevision(array1, array2)` を使えば、任意の __N__ 個に対応することは簡単にできることを補足3に追記しました。
24
+
25
+
20
26
 
21
27
 
22
28
 

36

テキスト修正

2019/01/16 04:16

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -242,8 +242,34 @@
242
242
 
243
243
     
244
244
 
245
+ ### 補足3
246
+
247
+
248
+
249
+ 任意の __N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理について補足しておきます。
250
+
251
+ ご質問にあるような、2つの配列 `array1`, `array2`を引数として受け取る
252
+
253
+
254
+
255
+ `function mergeArrayBasedIDByRevision(array1, array2)`
256
+
257
+
258
+
259
+ を作っておけば、__N__ 個の配列 ar1, ar2, ... ar__N__ から result を作る処理は、以下のようにすれば済みます。
260
+
261
+
262
+
263
+ ```
264
+
265
+ const result = [ar1, ar2, ... arN].reduce(mergeArrayBasedIDByRevision);
266
+
267
+ ```
268
+
269
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/h6ob920e/7/](https://jsfiddle.net/jun68ykt/h6ob920e/7/)
270
+
245
271
    
246
272
 
247
-    
248
-
273
+
274
+
249
- 以上参考にれば幸いです。
275
+ 回答のコード1とコード2でも使いましたが[reduce](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)を使いこせると色々な場面重宝します。

35

テキスト修正

2019/01/16 04:01

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -228,7 +228,7 @@
228
228
 
229
229
 
230
230
 
231
- このご質問の場合、idをキーとする何らかのマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由するのが適切なときに、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率なロジックになってしまっていることが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
231
+ このご質問の場合、idをキーとする何らかのマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の6つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由するのが適切なときに、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率なロジックになってしまっていることが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
232
232
 
233
233
 
234
234
 

34

テキスト修正

2019/01/15 07:42

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -192,6 +192,38 @@
192
192
 
193
193
 
194
194
 
195
+
196
+
197
+ ### コード6 (コード3の修正版)
198
+
199
+
200
+
201
+ 先に挙げたコード3の問題点だった、filter の判定 `i === ary.findIndex(e3 => e3.id === e.id)` を修正しました。
202
+
203
+
204
+
205
+ ```javascript
206
+
207
+ function mergeArrayBasedIDByRevision(array1, array2) {
208
+
209
+ return array1.concat(array2)
210
+
211
+ .sort((e1, e2) => e1.id.localeCompare(e2.id) || e2.rev - e1.rev)
212
+
213
+ .filter((e, i, ary) => i === 0 || e.id !== ary[i-1].id);
214
+
215
+ }
216
+
217
+ ```
218
+
219
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/h6ob920e/1/](https://jsfiddle.net/jun68ykt/h6ob920e/1/)
220
+
221
+
222
+
223
+
224
+
225
+
226
+
195
227
  ### 補足
196
228
 
197
229
 
@@ -200,4 +232,18 @@
200
232
 
201
233
 
202
234
 
235
+
236
+
237
+ ### 補足2
238
+
239
+
240
+
241
+ コード3の問題点を修正したコード6を追記しました。この修正によって、idをキーとするMapやプレーンオブジェクトを経由しないで配列のままでどうにかする方法の一案として、そこそこ実用に耐えうるものになったのではと思います。
242
+
243
+    
244
+
245
+   
246
+
247
+    
248
+
203
249
  以上、参考になれば幸いです。

33

テキスト修正

2019/01/15 00:47

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -196,7 +196,7 @@
196
196
 
197
197
 
198
198
 
199
- このご質問の場合、idをキーとするマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由するのが適切なときに、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率なロジックになってしまっていることが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
199
+ このご質問の場合、idをキーとする何らかのマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由するのが適切なときに、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率なロジックになってしまっていることが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
200
200
 
201
201
 
202
202
 

32

テキスト修正

2019/01/15 00:13

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -132,7 +132,7 @@
132
132
 
133
133
 
134
134
 
135
- array1 と array2を結合した配列を revの**昇順**でソートし、map で各要素を適切したうえで、Object.assign ないし Mapのコンストラクターに渡します。
135
+ array1 と array2を結合した配列を revの**昇順**でソートし、map で各要素を適切に変形したうえで、Object.assign ないし Mapのコンストラクターに渡します。
136
136
 
137
137
 
138
138
 

31

テキスト修正

2019/01/14 17:00

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -196,7 +196,7 @@
196
196
 
197
197
 
198
198
 
199
- このご質問の場合、idをキーととするマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由するのが適切なときに、配列のままで filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
199
+ このご質問の場合、idをキーととするマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由するのが適切なときに、配列のままで filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率なロジックになってしまっていることが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
200
200
 
201
201
 
202
202
 

30

テキスト修正

2019/01/14 16:52

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -196,7 +196,7 @@
196
196
 
197
197
 
198
198
 
199
- このご質問の場合、idをキーととするマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由する適切なときに、配列のままで filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
199
+ このご質問の場合、idをキーととするマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由するのが適切なときに、配列のままで filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
200
200
 
201
201
 
202
202
 

29

テキスト修正

2019/01/14 16:34

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -196,7 +196,7 @@
196
196
 
197
197
 
198
198
 
199
- このご質問の場合、idをキーととするマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由すると良いときに、配列のままで filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
199
+ このご質問の場合、idをキーととするマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由すると適切なときに、配列のままで filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
200
200
 
201
201
 
202
202
 

28

テキスト修正

2019/01/14 16:31

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -152,13 +152,15 @@
152
152
 
153
153
  .map(e => ({[e.id]: e}))
154
154
 
155
+ )
156
+
155
- ));
157
+ );
156
-
158
+
157
- }
159
+ }
158
-
160
+
159
- ```
161
+ ```
160
-
162
+
161
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/12/](https://jsfiddle.net/jun68ykt/jf1283mg/12/)
163
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/13/](https://jsfiddle.net/jun68ykt/jf1283mg/13/)
162
164
 
163
165
 
164
166
 

27

テキスト修正

2019/01/14 15:32

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -148,34 +148,34 @@
148
148
 
149
149
  ...array1.concat(array2)
150
150
 
151
+ .sort((e1, e2) => e1.rev - e2.rev)
152
+
153
+ .map(e => ({[e.id]: e}))
154
+
155
+ ));
156
+
157
+ }
158
+
159
+ ```
160
+
161
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/12/](https://jsfiddle.net/jun68ykt/jf1283mg/12/)
162
+
163
+
164
+
165
+ #### コード5
166
+
167
+ ```javascript
168
+
169
+ function mergeArrayBasedIDByRevision(array1, array2) {
170
+
171
+ return [...
172
+
173
+ new Map(
174
+
175
+ array1.concat(array2)
176
+
151
177
  .sort((e1, e2) => e1.rev - e2.rev)
152
178
 
153
- .map(e => ({[e.id]: e}))
154
-
155
- ));
156
-
157
- }
158
-
159
- ```
160
-
161
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/10/](https://jsfiddle.net/jun68ykt/jf1283mg/10/)
162
-
163
-
164
-
165
- #### コード5
166
-
167
- ```javascript
168
-
169
- function mergeArrayBasedIDByRevision(array1, array2) {
170
-
171
- return [...
172
-
173
- new Map(
174
-
175
- array1.concat(array2)
176
-
177
- .sort((e1, e2) => e1.rev - e2.rev)
178
-
179
179
  .map(e => [e.id, e])
180
180
 
181
181
  ).values()

26

テキスト修正

2019/01/14 15:28

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
 
15
- とあったので、この問題の処理のために最適化されたアルゴリズムをお求めなのではなく、`for`を使うかわりに map やfilter といった、( __"イテレーター的な" __とおっしゃるところの)便利な関数を使ったやり方をお求めかと思われましたので、以下、複数のコードを回答します。
15
+ とあったので、この問題の処理のために最適化されたアルゴリズムというよりも、`for`を使うかわりに map やfilter といった、( __"イテレーター的な" __とおっしゃるところの)便利な関数を使ったやり方をお求めかと思われましたので、以下、そのような関数の事例となるように複数のコードを回答します。
16
16
 
17
17
 
18
18
 

25

テキスト修正

2019/01/14 15:20

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- (※なお以下の回答コードでは、2つの配列の連結についてはご質問の本題ではないので、ご質問のコードでお使いになっている concat をそのまま使いますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。また、関数の引数 array1 と array2 の nullまたはundefinedチェック本題ではなので行っていません。)
19
+ (※なお以下の回答コードでは、2つの配列の連結についてはご質問の本題ではないので、ご質問のコードでお使いになっている concat をそのまま使いますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。また、関数の引数 array1 と array2 の2つから、任意の個数にすることご質問の要件にはなかったので未対応です。)
20
20
 
21
21
 
22
22
 

24

テキスト修正

2019/01/14 15:18

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -194,7 +194,7 @@
194
194
 
195
195
 
196
196
 
197
- このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
197
+ このご質問の場合、idをキーととするマップ構造(JavaScriptならプレーンオブジェクトかMapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由すると良いときに、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
198
198
 
199
199
 
200
200
 

23

テキスト修正

2019/01/14 14:59

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -194,7 +194,7 @@
194
194
 
195
195
 
196
196
 
197
- このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋の良い方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
197
+ このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが順当な方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
198
198
 
199
199
 
200
200
 

22

テキスト修正

2019/01/14 14:25

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
 
15
- とあ `for`を使わ色々なやり方をお求めかと思われましたので、以下、複数のコードを回答します。
15
+ とあったのでこの問題の処理のために最適化されたアルゴリズムをお求めなのではなく、`for`を使うかりに map やfilter とった、( __"イテレーター的" __とおっしゃるところの)便利な関数を使ったやり方をお求めかと思われましたので、以下、複数のコードを回答します。
16
16
 
17
17
 
18
18
 

21

テキスト修正

2019/01/14 14:19

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -132,7 +132,7 @@
132
132
 
133
133
 
134
134
 
135
- ar1とar2を結合した配列を revの**昇順**でソートし、map で各要素を適切な形にしたうえで、Object.assign ないし Mapのコンストラクターに渡します。
135
+ array1 array2を結合した配列を revの**昇順**でソートし、map で各要素を適切な形にしたうえで、Object.assign ないし Mapのコンストラクターに渡します。
136
136
 
137
137
 
138
138
 

20

テキスト修正

2019/01/14 14:09

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -194,7 +194,7 @@
194
194
 
195
195
 
196
196
 
197
- このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋の良い方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方をお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
197
+ このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋の良い方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方を参考にされることをお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
198
198
 
199
199
 
200
200
 

19

テキスト修正

2019/01/14 14:01

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- (※なお、以下の回答コードでは、2つの配列の連結についてはこのご質問の本題ではないので、ご質問のコードでお使いになっている concat をそのまま使います。また、関数に入った直後での array1 と array2 の nullまたはundefinedチェックも本題ではないので行っていません。)
19
+ (※なお、以下の回答コードでは、2つの配列の連結についてはご質問の本題ではないので、ご質問のコードでお使いになっている concat をそのまま使いますが、ご興味あれば[この質問と回答](https://stackoverflow.com/questions/5080028/)が面白いかもしれません。また、関数の引数 array1 と array2 の nullまたはundefinedチェックも本題ではないので行っていません。)
20
20
 
21
21
 
22
22
 

18

テキスト修正

2019/01/14 13:58

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -194,7 +194,7 @@
194
194
 
195
195
 
196
196
 
197
- このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋良いと思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方をお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
197
+ このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋良い方法と思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方をお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
198
198
 
199
199
 
200
200
 

17

テキスト修正

2019/01/14 13:49

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -124,7 +124,7 @@
124
124
 
125
125
 
126
126
 
127
- ただし、要素すべてについて`ary.findIndex(e3 => e3.id === e.id)`をやるので無駄が多いです。
127
+ ただし、要素すべてについて`ary.findIndex(e3 => e3.id === e.id)`を毎回やるので無駄が多いです。
128
128
 
129
129
 
130
130
 

16

テキスト修正

2019/01/14 13:47

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -16,6 +16,10 @@
16
16
 
17
17
 
18
18
 
19
+ (※なお、以下の回答のコードでは、2つの配列の連結についてはこのご質問の本題ではないので、ご質問のコードでお使いになっている concat をそのまま使います。また、関数に入った直後での array1 と array2 の nullまたはundefinedチェックも本題ではないので行っていません。)
20
+
21
+
22
+
19
23
  ### コード1
20
24
 
21
25
 
@@ -26,51 +30,35 @@
26
30
 
27
31
  ```javascript
28
32
 
29
- const ar1 = [{id: 'a1', rev: 1, val: 10}, {id: 'a2', rev: 2, val: 15}, {id: 'b1', rev: 1, val: 20}];
33
+ function mergeArrayBasedIDByRevision(array1, array2) {
30
-
31
- const ar2 = [{id: 'a1', rev: 2, val: 11}, {id: 'a2', rev: 1, val: 12}, {id: 'c1', rev: 2, val: 30}];
34
+
32
-
33
-
34
-
35
- const result = [...
35
+ return [...
36
+
36
-
37
+ array1
38
+
37
- ar1.concat(ar2)
39
+ .concat(array2)
38
-
40
+
39
- .reduce(
41
+ .reduce(
40
-
42
+
41
- (map, e) =>
43
+ (map, e) =>
42
-
44
+
43
- (map.get(e.id) || {}).rev >= e.rev
45
+ (map.get(e.id) || {}).rev >= e.rev
44
-
46
+
45
- ? map
47
+ ? map
46
-
48
+
47
- : map.set(e.id, e)
49
+ : map.set(e.id, e)
48
-
50
+
49
- , new Map())
51
+ , new Map())
50
-
52
+
51
- .values()
53
+ .values()
52
-
54
+
53
- ];
55
+ ];
54
-
55
-
56
-
56
+
57
- console.log(result);
57
+ }
58
-
58
+
59
- ```
59
+ ```
60
-
61
- 出力結果:
60
+
62
-
63
- > [ { id: 'a1', rev: 2, val: 11 },
64
-
65
- { id: 'a2', rev: 2, val: 15 },
66
-
67
- { id: 'b1', rev: 1, val: 20 },
68
-
69
- { id: 'c1', rev: 2, val: 30 } ]
70
-
71
-
72
-
73
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/suL7tx3k/2/](https://jsfiddle.net/jun68ykt/suL7tx3k/2/)
61
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/suL7tx3k/12/](https://jsfiddle.net/jun68ykt/suL7tx3k/12/)
74
62
 
75
63
 
76
64
 
@@ -80,29 +68,31 @@
80
68
 
81
69
 
82
70
 
83
- Map を使わず find と filter を使った別解です。
71
+ Map を使わず find と filter を使ってみコードです。
84
-
72
+
85
- ```javascript
73
+ ```javascript
74
+
86
-
75
+ function mergeArrayBasedIDByRevision(array1, array2) {
76
+
87
- const result = ar1.concat(ar2).reduce(
77
+ return array1.concat(array2).reduce(
88
-
78
+
89
- (ary, e) =>
79
+ (ary, e) =>
90
-
80
+
91
- (ary.find(e2 => e2.id === e.id) || {}).rev >= e.rev
81
+ (ary.find(e2 => e2.id === e.id) || {}).rev >= e.rev
92
-
82
+
93
- ? ary
83
+ ? ary
94
-
84
+
95
- : [...ary.filter(e3 => e3.id !== e.id), e]
85
+ : [...ary.filter(e3 => e3.id !== e.id), e]
96
-
86
+
97
- ,[]
87
+ , []
98
-
88
+
99
- );
89
+ );
90
+
100
-
91
+ }
92
+
101
- ```
93
+ ```
102
-
103
-
104
-
94
+
105
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/b9kseywr/8/](https://jsfiddle.net/jun68ykt/b9kseywr/8/)
95
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/b9kseywr/10/](https://jsfiddle.net/jun68ykt/b9kseywr/10/)
106
96
 
107
97
 
108
98
 
@@ -118,15 +108,19 @@
118
108
 
119
109
  ```javascript
120
110
 
111
+ function mergeArrayBasedIDByRevision(array1, array2) {
112
+
121
- const result = ar1.concat(ar2)
113
+ return array1.concat(array2)
122
-
114
+
123
- .sort((e1, e2) => e1.id.localeCompare(e2.id) || e2.rev - e1.rev)
115
+ .sort((e1, e2) => e1.id.localeCompare(e2.id) || e2.rev - e1.rev)
124
-
116
+
125
- .filter((e, i, ary) => i === ary.findIndex(e3 => e3.id === e.id));
117
+ .filter((e, i, ary) => i === ary.findIndex(e3 => e3.id === e.id));
118
+
126
-
119
+ }
120
+
127
- ```
121
+ ```
128
-
122
+
129
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/zLodvq7c/2/](https://jsfiddle.net/jun68ykt/zLodvq7c/2/)
123
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/zLodvq7c/3/](https://jsfiddle.net/jun68ykt/zLodvq7c/3/)
130
124
 
131
125
 
132
126
 
@@ -146,23 +140,25 @@
146
140
 
147
141
  ```javascript
148
142
 
143
+ function mergeArrayBasedIDByRevision(array1, array2) {
144
+
149
- const result = Object.values(
145
+ return Object.values(
150
-
146
+
151
- Object.assign({},
147
+ Object.assign({},
152
-
148
+
153
- ...ar1.concat(ar2)
149
+ ...array1.concat(array2)
154
-
150
+
155
- .sort((e1, e2) => e1.rev - e2.rev)
151
+ .sort((e1, e2) => e1.rev - e2.rev)
156
-
152
+
157
- .map(e => ({[e.id]: e}))
153
+ .map(e => ({[e.id]: e}))
158
-
159
- )
154
+
160
-
161
- );
155
+ ));
156
+
162
-
157
+ }
158
+
163
- ```
159
+ ```
164
-
160
+
165
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/8/](https://jsfiddle.net/jun68ykt/jf1283mg/8/)
161
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/10/](https://jsfiddle.net/jun68ykt/jf1283mg/10/)
166
162
 
167
163
 
168
164
 
@@ -170,23 +166,27 @@
170
166
 
171
167
  ```javascript
172
168
 
169
+ function mergeArrayBasedIDByRevision(array1, array2) {
170
+
173
- const result = [...
171
+ return [...
174
-
172
+
175
- new Map(
173
+ new Map(
176
-
174
+
177
- ar1.concat(ar2)
175
+ array1.concat(array2)
178
-
176
+
179
- .sort((e1, e2) => e1.rev - e2.rev)
177
+ .sort((e1, e2) => e1.rev - e2.rev)
180
-
178
+
181
- .map(e => [e.id, e])
179
+ .map(e => [e.id, e])
182
-
180
+
183
- ).values()
181
+ ).values()
184
-
182
+
185
- ];
183
+ ];
184
+
186
-
185
+ }
186
+
187
- ```
187
+ ```
188
-
188
+
189
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/a4hpgLtn/2/](https://jsfiddle.net/jun68ykt/a4hpgLtn/2/)
189
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/a4hpgLtn/3/](https://jsfiddle.net/jun68ykt/a4hpgLtn/3/)
190
190
 
191
191
 
192
192
 
@@ -194,4 +194,8 @@
194
194
 
195
195
 
196
196
 
197
- このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋が良いと思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 をお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
197
+ このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋が良いと思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 のやり方をお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても、非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。
198
+
199
+
200
+
201
+ 以上、参考になれば幸いです。

15

テキスト修正

2019/01/14 13:44

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -194,4 +194,4 @@
194
194
 
195
195
 
196
196
 
197
- このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋が良いと思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 をお勧めします。コード2, 3 は、マップ構造を使うと良いような状況で、配列のまま filterやfindで頑張ろうとすると、見た目ではコードを短くできても非効率な動作をしてしまう例と思って頂いてかまいません。
197
+ このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋が良いと思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 をお勧めします。配列からいったんマップ構造を経由すると良いような状況で、配列のまま filterやfindで頑張ろうとすると、要件を満たせて見た目上のコードを短くできたとしても非効率な動作をしてしまうことが、ままあります。コード2, 3 は、そのような例と思って頂いてかまいません。

14

テキスト修正お

2019/01/14 10:32

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -187,3 +187,11 @@
187
187
  ```
188
188
 
189
189
  - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/a4hpgLtn/2/](https://jsfiddle.net/jun68ykt/a4hpgLtn/2/)
190
+
191
+
192
+
193
+ ### 補足
194
+
195
+
196
+
197
+ このご質問の場合、idをキーとし各要素を値とするマップ構造(JavaScriptならプレーンオブジェクトか、Mapオブジェクト)を経由するのが筋が良いと思われますので、上記の5つの中で選ぶとすれば、コード1, 4, 5 をお勧めします。コード2, 3 は、マップ構造を使うと良いような状況で、配列のまま filterやfindで頑張ろうとすると、見た目ではコードを短くできても非効率な動作をしてしまう例と思って頂いてかまいません。

13

テキスト修正

2019/01/14 10:24

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -16,7 +16,11 @@
16
16
 
17
17
 
18
18
 
19
+ ### コード1
20
+
21
+
22
+
19
- まず、以下は reduce, Map, スプレッド構文を使ったコードです。
23
+ reduce, Map, スプレッド構文を使います。
20
24
 
21
25
 
22
26
 
@@ -72,9 +76,7 @@
72
76
 
73
77
 
74
78
 
75
-
76
-
77
- ### 別解1
79
+ ### コード2
78
80
 
79
81
 
80
82
 
@@ -108,7 +110,7 @@
108
110
 
109
111
 
110
112
 
111
- ### 別解2
113
+ ### コード3
112
114
 
113
115
 
114
116
 
@@ -132,13 +134,15 @@
132
134
 
133
135
 
134
136
 
135
- ### 別解3, 4
137
+ ### コード4,5
136
138
 
137
139
 
138
140
 
139
141
  ar1とar2を結合した配列を revの**昇順**でソートし、map で各要素を適切な形にしたうえで、Object.assign ないし Mapのコンストラクターに渡します。
140
142
 
141
143
 
144
+
145
+ #### コード4
142
146
 
143
147
  ```javascript
144
148
 
@@ -158,6 +162,12 @@
158
162
 
159
163
  ```
160
164
 
165
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/8/](https://jsfiddle.net/jun68ykt/jf1283mg/8/)
166
+
167
+
168
+
169
+ #### コード5
170
+
161
171
  ```javascript
162
172
 
163
173
  const result = [...
@@ -176,6 +186,4 @@
176
186
 
177
187
  ```
178
188
 
179
-
180
-
181
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/4/](https://jsfiddle.net/jun68ykt/jf1283mg/4/)
189
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/a4hpgLtn/2/](https://jsfiddle.net/jun68ykt/a4hpgLtn/2/)

12

テキスト修正

2019/01/14 09:47

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -98,7 +98,13 @@
98
98
 
99
99
  ```
100
100
 
101
+
102
+
101
103
  - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/b9kseywr/8/](https://jsfiddle.net/jun68ykt/b9kseywr/8/)
104
+
105
+
106
+
107
+ ただし、`e.id`と同じidの要素が除去された配列を作るのに、`ary.filter(e3 => e3.id !== e.id)` としている所が無駄です。なぜかというと`ary.filter` とすると `ary`の全要素を走査してしまいますが、`ary`の中には同じ`id`の要素は最大でも1個しかないからです。
102
108
 
103
109
 
104
110
 

11

テキスト修正

2019/01/14 09:26

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -130,7 +130,7 @@
130
130
 
131
131
 
132
132
 
133
- 2つ思いつきましたのでておきます。
133
+ ar1ar2を結合した配列を rev**昇順**ソートし、map で各要素を適切な形にしたうえで、Object.assign なし Mapのコンストラクターに渡します。
134
134
 
135
135
 
136
136
 

10

テキスト修正

2019/01/14 09:20

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -2,7 +2,21 @@
2
2
 
3
3
 
4
4
 
5
+ ご質問に
6
+
7
+
8
+
9
+ > そこでforを使った関数を作成しましたが、どうも見辛くスマートさに欠けるため
10
+
11
+ mapやfilterなどのイテレーター的な関数を使って書き直せないものかと思っています。
12
+
13
+
14
+
15
+ とあり、 `for`を使わない色々なやり方をお求めかと思われましたので、以下、複数のコードを回答します。
16
+
17
+
18
+
5
- reduce, Map, スプレッド構文を使ってみました。
19
+ まず、以下は reduce, Map, スプレッド構文を使ったコードです
6
20
 
7
21
 
8
22
 
@@ -56,11 +70,11 @@
56
70
 
57
71
 
58
72
 
59
- 以上参考になれば幸いです。
60
73
 
61
74
 
62
75
 
76
+
63
- ### 追記1
77
+ ### 別解1
64
78
 
65
79
 
66
80
 
@@ -88,11 +102,11 @@
88
102
 
89
103
 
90
104
 
91
- ### 追記2
105
+ ### 別解2
92
106
 
93
107
 
94
108
 
95
- もうひとつ別解です。ar1 と ar2 を結合して、**idの昇順+revの降順**でソートし、ソート結果から各idのrevが最大のものだけをピックアップします。
109
+ ar1 と ar2 を結合して、**idの昇順+revの降順**でソートし、ソート結果から各idのrevが最大のものだけをピックアップします。
96
110
 
97
111
  ```javascript
98
112
 
@@ -112,23 +126,11 @@
112
126
 
113
127
 
114
128
 
115
- ### 追記3
129
+ ### 別解3, 4
116
130
 
117
131
 
118
132
 
119
- あと2つ思いつきました。
133
+ あと2つ思いつきましたので書いておきます
120
-
121
- ご質問に
122
-
123
-
124
-
125
- > そこでforを使った関数を作成しましたが、どうも見辛くスマートさに欠けるため
126
-
127
- mapやfilterなどのイテレーター的な関数を使って書き直せないものかと思っています。
128
-
129
-
130
-
131
- とあり、 `for`を使わない色々なやり方をお求めかと思われましたので書いておきます。
132
134
 
133
135
 
134
136
 

9

テキスト修正

2019/01/14 09:16

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -116,7 +116,19 @@
116
116
 
117
117
 
118
118
 
119
+ あと2つ思いつきました。
120
+
121
+ ご質問に
122
+
123
+
124
+
125
+ > そこでforを使った関数を作成しましたが、どうも見辛くスマートさに欠けるため
126
+
127
+ mapやfilterなどのイテレーター的な関数を使って書き直せないものかと思っています。
128
+
129
+
130
+
119
- と2つ思いつきました。ご質問の主旨からすると、`for`を使わない色々なやり方をお求めかと思ましたので書いておきます。
131
+ `for`を使わない色々なやり方をお求めかと思われましたので書いておきます。
120
132
 
121
133
 
122
134
 

8

テキスト修正

2019/01/14 08:58

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -132,7 +132,9 @@
132
132
 
133
133
  .map(e => ({[e.id]: e}))
134
134
 
135
+ )
136
+
135
- ));
137
+ );
136
138
 
137
139
  ```
138
140
 
@@ -156,4 +158,4 @@
156
158
 
157
159
 
158
160
 
159
- - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/3/](https://jsfiddle.net/jun68ykt/jf1283mg/3/)
161
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/4/](https://jsfiddle.net/jun68ykt/jf1283mg/4/)

7

テキスト修正

2019/01/14 08:37

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -109,3 +109,51 @@
109
109
 
110
110
 
111
111
  ただし、要素すべてについて`ary.findIndex(e3 => e3.id === e.id)`をやるので無駄が多いです。
112
+
113
+
114
+
115
+ ### 追記3
116
+
117
+
118
+
119
+ あと2つ思いつきました。ご質問の主旨からすると、`for`を使わない色々なやり方をお求めかと思いましたので書いておきます。
120
+
121
+
122
+
123
+ ```javascript
124
+
125
+ const result = Object.values(
126
+
127
+ Object.assign({},
128
+
129
+ ...ar1.concat(ar2)
130
+
131
+ .sort((e1, e2) => e1.rev - e2.rev)
132
+
133
+ .map(e => ({[e.id]: e}))
134
+
135
+ ));
136
+
137
+ ```
138
+
139
+ ```javascript
140
+
141
+ const result = [...
142
+
143
+ new Map(
144
+
145
+ ar1.concat(ar2)
146
+
147
+ .sort((e1, e2) => e1.rev - e2.rev)
148
+
149
+ .map(e => [e.id, e])
150
+
151
+ ).values()
152
+
153
+ ];
154
+
155
+ ```
156
+
157
+
158
+
159
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/jf1283mg/3/](https://jsfiddle.net/jun68ykt/jf1283mg/3/)

6

テキスト修正

2019/01/14 08:30

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -108,4 +108,4 @@
108
108
 
109
109
 
110
110
 
111
- ただし、あるidの要素すべてについて毎回、`ary.findIndex(e3 => e3.id === e.id)`をやるのでかなり無駄が多いです。
111
+ ただし、要素すべてについて`ary.findIndex(e3 => e3.id === e.id)`をやるので無駄が多いです。

5

テキスト修正

2019/01/14 07:26

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -105,3 +105,7 @@
105
105
  ```
106
106
 
107
107
  - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/zLodvq7c/2/](https://jsfiddle.net/jun68ykt/zLodvq7c/2/)
108
+
109
+
110
+
111
+ ただし、あるidの要素すべてについて毎回、`ary.findIndex(e3 => e3.id === e.id)`をやるのでかなり無駄が多いです。

4

テキスト修正

2019/01/14 06:59

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -92,7 +92,7 @@
92
92
 
93
93
 
94
94
 
95
- もうひとつ別解です。ar1 と ar2 を結合して、**idの昇順+revの降順**でソートし、ソート結果から各idのrevが最大のものだけをピッアップします。
95
+ もうひとつ別解です。ar1 と ar2 を結合して、**idの昇順+revの降順**でソートし、ソート結果から各idのrevが最大のものだけをピッアップします。
96
96
 
97
97
  ```javascript
98
98
 

3

テキスト修正

2019/01/14 06:32

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -60,7 +60,7 @@
60
60
 
61
61
 
62
62
 
63
- ### 追記
63
+ ### 追記1
64
64
 
65
65
 
66
66
 
@@ -85,3 +85,23 @@
85
85
  ```
86
86
 
87
87
  - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/b9kseywr/8/](https://jsfiddle.net/jun68ykt/b9kseywr/8/)
88
+
89
+
90
+
91
+ ### 追記2
92
+
93
+
94
+
95
+ もうひとつ別解です。ar1 と ar2 を結合して、**idの昇順+revの降順**でソートし、ソート結果から各idのrevが最大のものだけをピッアップします。
96
+
97
+ ```javascript
98
+
99
+ const result = ar1.concat(ar2)
100
+
101
+ .sort((e1, e2) => e1.id.localeCompare(e2.id) || e2.rev - e1.rev)
102
+
103
+ .filter((e, i, ary) => i === ary.findIndex(e3 => e3.id === e.id));
104
+
105
+ ```
106
+
107
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/zLodvq7c/2/](https://jsfiddle.net/jun68ykt/zLodvq7c/2/)

2

テキスト修正

2019/01/14 06:27

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -64,7 +64,7 @@
64
64
 
65
65
 
66
66
 
67
- Map を使わず filter を使った別解です。
67
+ Map を使わず find と filter を使った別解です。
68
68
 
69
69
  ```javascript
70
70
 

1

テキスト修正

2019/01/14 05:16

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -57,3 +57,31 @@
57
57
 
58
58
 
59
59
  以上参考になれば幸いです。
60
+
61
+
62
+
63
+ ### 追記
64
+
65
+
66
+
67
+ Map を使わず filter を使った別解です。
68
+
69
+ ```javascript
70
+
71
+ const result = ar1.concat(ar2).reduce(
72
+
73
+ (ary, e) =>
74
+
75
+ (ary.find(e2 => e2.id === e.id) || {}).rev >= e.rev
76
+
77
+ ? ary
78
+
79
+ : [...ary.filter(e3 => e3.id !== e.id), e]
80
+
81
+ ,[]
82
+
83
+ );
84
+
85
+ ```
86
+
87
+ - **動作確認用のサンプル: ** [https://jsfiddle.net/jun68ykt/b9kseywr/8/](https://jsfiddle.net/jun68ykt/b9kseywr/8/)