回答編集履歴

17

テキスト修正

2019/09/01 01:14

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -84,7 +84,17 @@
84
84
 
85
85
 
86
86
 
87
- ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の(ご質問にあるコードで、ソートした後の最新日付のデータ抽出時に、`filter`に与える関数をどう書けばいいか。)からは外れます。それゆえ、あくまでご参考に留めて頂ければと思います。
87
+ ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の
88
+
89
+
90
+
91
+ > ●質問内容
92
+
93
+ 上記1やりたいこと1は思うように並び替え出来た様ですが、やりたいこと2の抽出がfilterで抽出すると思うのですが、どの様に条件付ければ良いか分かりません。
94
+
95
+
96
+
97
+ からは外れます。それゆえ、あくまでご参考に留めて頂ければと思います。
88
98
 
89
99
 
90
100
 

16

テキスト修正

2019/09/01 01:14

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -84,7 +84,7 @@
84
84
 
85
85
 
86
86
 
87
- ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の本題(ご質問にあるコードで、`filter`の条件をどう書けばいいか。)からは外れます。それゆえ、あくまでご参考に留めて頂ければと思います。
87
+ ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の本題(ご質問にあるコードで、ソートした後の最新日付のデータ抽出時に、`filter`に与える関数をどう書けばいいか。)からは外れます。それゆえ、あくまでご参考に留めて頂ければと思います。
88
88
 
89
89
 
90
90
 

15

テキスト修正

2019/09/01 00:17

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -84,7 +84,7 @@
84
84
 
85
85
 
86
86
 
87
- ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、 `sort` するところから見直ますので、ご質問の本題(ご質問にあるコードで、`filter`の条件をどう書けばいいか。)からはやや外れます。あくまで参考に留めて頂ければと思います。
87
+ ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の本題(ご質問にあるコードで、`filter`の条件をどう書けばいいか。)からは外れます。それゆえ、あくまで参考に留めて頂ければと思います。
88
88
 
89
89
 
90
90
 

14

テキスト修正

2019/09/01 00:05

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -220,4 +220,4 @@
220
220
 
221
221
 
222
222
 
223
- は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使追記2のコードの中間生成物としてMapを作のを省き、コード量を減らしたものです。
223
+ は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、中間生成物としてMapを作っていたのを省き、コード量を減らしたものです。

13

テキスト修正

2019/08/31 12:33

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -212,12 +212,12 @@
212
212
 
213
213
 
214
214
 
215
- 以下
215
+ 追記2 の修正版です。以下
216
-
217
-
218
-
216
+
217
+
218
+
219
- - [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)
219
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)
220
-
221
-
222
-
220
+
221
+
222
+
223
- は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、追記2のコードから中間Mapを作るのを省き、コード量を減らしたものです。
223
+ は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使、追記2のコード中間生成物として、Mapを作るのを省き、コード量を減らしたものです。

12

テキスト修正

2019/08/31 12:31

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -212,8 +212,12 @@
212
212
 
213
213
 
214
214
 
215
+ 以下
216
+
217
+
218
+
219
+ - [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)
220
+
221
+
222
+
215
- 以下は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、追記2のコードから中間でMapを作るのを省き、コード量を減らしたものです。
223
+ は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、追記2のコードから中間でMapを作るのを省き、コード量を減らしたものです。
216
-
217
-
218
-
219
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)

11

テキスト修正

2019/08/31 12:01

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -205,3 +205,15 @@
205
205
 
206
206
 
207
207
  - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/12/](https://jsfiddle.net/jun68ykt/619atrpj/12/)
208
+
209
+
210
+
211
+ ### 追記3
212
+
213
+
214
+
215
+ 以下は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、追記2のコードから中間でMapを作るのを省き、コード量を減らしたものです。
216
+
217
+
218
+
219
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)

10

テキスト修正

2019/08/31 12:00

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -80,7 +80,11 @@
80
80
 
81
81
 
82
82
 
83
+ 別解を挙げます。要所要所で便利なライブラリの力を借ります。
84
+
85
+
86
+
83
- 別解を挙げます。ただし、この別解は、ご質問に挙げられているコードの中で、 `filter` する行だけではなく、ソートするところから見直します。また、外部ライブラリの力を借りる案なので、ご質問の本題(ご質問にあるコードで、filterの条件をどう書けばいいか。)からはやや外れますから、あくまで参考に留めて頂ければと思います。
87
+ ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、 `sort` するところから見直しますので、ご質問の本題(ご質問にあるコードで、`filter`の条件をどう書けばいいか。)からはやや外れますあくまで参考に留めて頂ければと思います。
84
88
 
85
89
 
86
90
 
@@ -196,7 +200,7 @@
196
200
 
197
201
 
198
202
 
199
- 上記のコードでは、 各キーに対して、日付が最新の要素(である配列)を取得するときに、 [_.maxBy](https://lodash.com/docs/#maxBy) も使っています。
203
+ 上記のコードでは、 各キーに対して、日付が最新の要素(である配列)を取得するときに、Lodashの [_.maxBy](https://lodash.com/docs/#maxBy) も使っています。
200
204
 
201
205
 
202
206
 

9

テキスト修正

2019/08/31 11:12

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -180,9 +180,7 @@
180
180
 
181
181
  var keyToNewestDateMap = groupedEntries.reduce(
182
182
 
183
- (map, [key, arrays]) => map.set(key, _.maxBy(arrays, ary => ary[4])
183
+ (map, [key, arrays]) => map.set(key, _.maxBy(arrays, ary => ary[4])), new Map());
184
-
185
- ), new Map());
186
184
 
187
185
 
188
186
 
@@ -202,4 +200,4 @@
202
200
 
203
201
 
204
202
 
205
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/11/](https://jsfiddle.net/jun68ykt/619atrpj/11/)
203
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/12/](https://jsfiddle.net/jun68ykt/619atrpj/12/)

8

テキスト修正

2019/08/31 07:09

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -176,19 +176,13 @@
176
176
 
177
177
 
178
178
 
179
- // 各キーに対して、日付が最新の要素(である配列) を値とするマップを作成
179
+ // 各キーに対して、日付が最新の要素を値とするマップを作成
180
180
 
181
181
  var keyToNewestDateMap = groupedEntries.reduce(
182
182
 
183
- (map, [key, arrays]) =>
184
-
185
- map.set(
186
-
187
- key,
188
-
189
- arrays.sort((ary1, ary2) => ary2[4].localeCompare(ary1[4])).shift()
183
+ (map, [key, arrays]) => map.set(key, _.maxBy(arrays, ary => ary[4])
190
-
184
+
191
- ), new Map());
185
+ ), new Map());
192
186
 
193
187
 
194
188
 
@@ -204,4 +198,8 @@
204
198
 
205
199
 
206
200
 
201
+ 上記のコードでは、 各キーに対して、日付が最新の要素(である配列)を取得するときに、 [_.maxBy](https://lodash.com/docs/#maxBy) も使っています。
202
+
203
+
204
+
207
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/8/](https://jsfiddle.net/jun68ykt/619atrpj/8/)
205
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/11/](https://jsfiddle.net/jun68ykt/619atrpj/11/)

7

テキスト修正

2019/08/31 07:02

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -80,7 +80,7 @@
80
80
 
81
81
 
82
82
 
83
- 別解を挙げます。ただし、この別解は、ご質問に挙げられているコードの中で、 `filter` する行だけではなく、ソートするところから修正する案なので、ご質問の本題(filterの条件をどう書けばいいか。)はやや外れますので、あくまで参考に留めて頂ければと思います。
83
+ 別解を挙げます。ただし、この別解は、ご質問に挙げられているコードの中で、 `filter` する行だけではなく、ソートするところから見直しま。また、外部のライブラリの力を借りる案なので、ご質問の本題(ご質問にあるコードで、filterの条件をどう書けばいいか。)からはやや外れますから、あくまで参考に留めて頂ければと思います。
84
84
 
85
85
 
86
86
 

6

テキスト修正

2019/08/31 06:26

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -172,13 +172,13 @@
172
172
 
173
173
  // カテゴリ1,2,3をスラッシュを区切りとして連結した文字列をキーにグループ化したオブジェクトを得て、それのエントリ配列を取得
174
174
 
175
- var entries = Object.entries(_.groupBy(arr, ary => ary.slice(0,3).join('/')));
175
+ var groupedEntries = Object.entries(_.groupBy(arr, ary => ary.slice(0,3).join('/')));
176
176
 
177
177
 
178
178
 
179
179
  // 各キーに対して、日付が最新の要素(である配列) を値とするマップを作成
180
180
 
181
- var keyToNewestDateMap = entries.reduce(
181
+ var keyToNewestDateMap = groupedEntries.reduce(
182
182
 
183
183
  (map, [key, arrays]) =>
184
184
 
@@ -204,4 +204,4 @@
204
204
 
205
205
 
206
206
 
207
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/6/](https://jsfiddle.net/jun68ykt/619atrpj/6/)
207
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/8/](https://jsfiddle.net/jun68ykt/619atrpj/8/)

5

テキスト修正

2019/08/31 06:17

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -38,7 +38,7 @@
38
38
 
39
39
 
40
40
 
41
- ### 追記
41
+ ### 追記1
42
42
 
43
43
 
44
44
 

4

テキスト修正

2019/08/31 05:53

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -73,3 +73,135 @@
73
73
 
74
74
 
75
75
  - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/ao85qz0k/7/](https://jsfiddle.net/jun68ykt/ao85qz0k/7/)
76
+
77
+
78
+
79
+ ### 追記2
80
+
81
+
82
+
83
+ 別解を挙げます。ただし、この別解は、ご質問に挙げられているコードの中で、 `filter` する行だけではなく、ソートするところから修正する案なので、ご質問の本題(filterの条件をどう書けばいいか。)とはやや外れますので、あくまで参考に留めて頂ければと思います。
84
+
85
+
86
+
87
+ 配列やオブジェクトの操作で、便利なメソッドを提供しているライブラリ [Lodash](https://lodash.com/)に、 [_.groupBy](https://lodash.com/docs/#groupBy) というメソッドがあります。これを使うと配列の要素を何らかの値を基準にグルーピングしたオブジェクトを返してくれます。
88
+
89
+
90
+
91
+ このご質問の場合、カテゴリ1、カテゴリ2、カテゴリ3、それぞれの文字列を、たとえば `/` でjoinした文字列をその基準値に使ってグループ化することが考えられます。これは以下によって実現できます。
92
+
93
+ ```javascript
94
+
95
+ _.groupBy(arr, ary => ary.slice(0,3).join('/'))
96
+
97
+ ```
98
+
99
+ 上記の _.groupBy が返すのは、下記のようなオブジェクトです。
100
+
101
+
102
+
103
+ ```javascript
104
+
105
+ {
106
+
107
+ "a/a/a":[
108
+
109
+ [ "a", "a", "a", 1, "2019/01/01" ],
110
+
111
+ [ "a", "a", "a", 1, "2019/02/02" ]
112
+
113
+ ],
114
+
115
+ "a/b/a":[
116
+
117
+ [ "a", "b", "a", 1, "2019/01/01" ]
118
+
119
+ ],
120
+
121
+ "b/a/a":[
122
+
123
+ [ "b", "a", "a", 1, "2019/01/01" ]
124
+
125
+ ],
126
+
127
+ "a/a/c":[
128
+
129
+ [ "a", "a", "c", 1, "2019/01/01" ]
130
+
131
+ ],
132
+
133
+ "c/a/c":[
134
+
135
+ [ "c", "a", "c", 1, "2019/01/01" ],
136
+
137
+ [ "c", "a", "c", 1, "2019/07/01" ]
138
+
139
+ ],
140
+
141
+ "b/b/b":[
142
+
143
+ [ "b", "b", "b", 1, "2019/01/01" ]
144
+
145
+ ],
146
+
147
+ "b/b/a":[
148
+
149
+ [ "b", "b", "a", 1, "2019/01/01" ]
150
+
151
+ ],
152
+
153
+ "b/a/b":[
154
+
155
+ [ "b", "a", "b", 1, "2019/01/01" ]
156
+
157
+ ]
158
+
159
+ }
160
+
161
+ ```
162
+
163
+ 上記のように、 各カテゴリの値 `a` や `b` を `/` を区切り文字として連結した文字列が、オブジェクトのキーになり、各キーに該当する要素(である配列)が配列としてまとめられます。なお上記では、`/` を連結時の区切り文字としていますが、各カテゴリの文字列それ自体の中にも `/` が出現する可能性があるのであれば、何か他の、各カテゴリの文字列の中には出現しない文字(列)で連結します。
164
+
165
+
166
+
167
+ 以下は、上記の _.groupBy を使って `arr` から `arr2` を得るコード例です。
168
+
169
+
170
+
171
+ ```javascript
172
+
173
+ // カテゴリ1,2,3をスラッシュを区切りとして連結した文字列をキーにグループ化したオブジェクトを得て、それのエントリ配列を取得
174
+
175
+ var entries = Object.entries(_.groupBy(arr, ary => ary.slice(0,3).join('/')));
176
+
177
+
178
+
179
+ // 各キーに対して、日付が最新の要素(である配列) を値とするマップを作成
180
+
181
+ var keyToNewestDateMap = entries.reduce(
182
+
183
+ (map, [key, arrays]) =>
184
+
185
+ map.set(
186
+
187
+ key,
188
+
189
+ arrays.sort((ary1, ary2) => ary2[4].localeCompare(ary1[4])).shift()
190
+
191
+ ), new Map());
192
+
193
+
194
+
195
+ // 上記で作成したマップのエントリから、キー(カテゴリを / で連結した文字列)でソートされた、値の配列を取得
196
+
197
+ var arr2 = [...keyToNewestDateMap]
198
+
199
+ .sort(([key1], [key2]) => key1.localeCompare(key2))
200
+
201
+ .map(([_, v]) => v);
202
+
203
+ ```
204
+
205
+
206
+
207
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/6/](https://jsfiddle.net/jun68ykt/619atrpj/6/)

3

テキスト修正

2019/08/31 05:51

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -73,7 +73,3 @@
73
73
 
74
74
 
75
75
  - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/ao85qz0k/7/](https://jsfiddle.net/jun68ykt/ao85qz0k/7/)
76
-
77
-
78
-
79
- ###

2

テキスト修正

2019/08/31 04:56

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -69,3 +69,11 @@
69
69
  return x[0] !== y[0] || x[1] !== y[1] || x[2] !== y[2];
70
70
 
71
71
  ```
72
+
73
+
74
+
75
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/ao85qz0k/7/](https://jsfiddle.net/jun68ykt/ao85qz0k/7/)
76
+
77
+
78
+
79
+ ###

1

テキスト修正

2019/08/31 04:55

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -35,3 +35,37 @@
35
35
 
36
36
 
37
37
  以上、参考になれば幸いです。
38
+
39
+
40
+
41
+ ### 追記
42
+
43
+
44
+
45
+ 質問への追記・修正のほうから、以下のご回答を頂きました。
46
+
47
+
48
+
49
+ > カテゴリ値は二文字以上の文字列もあり得ます。
50
+
51
+
52
+
53
+ 上記に対応させるために、先に挙げたコードの `else` の場合の `return`文を、以下のように修正します。
54
+
55
+
56
+
57
+ **修正前:**
58
+
59
+ ```javascript
60
+
61
+ return `${x[0]}${x[1]}${x[2]}` !== `${y[0]}${y[1]}${y[2]}`;
62
+
63
+ ```
64
+
65
+ **修正後:**
66
+
67
+ ```javascript
68
+
69
+ return x[0] !== y[0] || x[1] !== y[1] || x[2] !== y[2];
70
+
71
+ ```