teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

17

テキスト修正

2019/09/01 01:14

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -41,8 +41,13 @@
41
41
 
42
42
  別解を挙げます。要所要所で便利なライブラリの力を借ります。
43
43
 
44
- ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の(ご質問にあるコードで、ソートした後の最新日付のデータ抽出時に、`filter`に与える関数をどう書けばいいか。)からは外れます。それゆえ、あくまでご参考に留めて頂ければと思います。
44
+ ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の
45
45
 
46
+ > ●質問内容
47
+ 上記1やりたいこと1は思うように並び替え出来た様ですが、やりたいこと2の抽出がfilterで抽出すると思うのですが、どの様に条件付ければ良いか分かりません。
48
+
49
+ からは外れます。それゆえ、あくまでご参考に留めて頂ければと思います。
50
+
46
51
  配列やオブジェクトの操作で、便利なメソッドを提供しているライブラリ [Lodash](https://lodash.com/)に、 [_.groupBy](https://lodash.com/docs/#groupBy) というメソッドがあります。これを使うと配列の要素を何らかの値を基準にグルーピングしたオブジェクトを返してくれます。
47
52
 
48
53
  このご質問の場合、カテゴリ1、カテゴリ2、カテゴリ3、それぞれの文字列を、たとえば `/` でjoinした文字列をその基準値に使ってグループ化することが考えられます。これは以下によって実現できます。

16

テキスト修正

2019/09/01 01:14

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -41,7 +41,7 @@
41
41
 
42
42
  別解を挙げます。要所要所で便利なライブラリの力を借ります。
43
43
 
44
- ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の本題(ご質問にあるコードで、`filter`の条件をどう書けばいいか。)からは外れます。それゆえ、あくまでご参考に留めて頂ければと思います。
44
+ ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の本題(ご質問にあるコードで、ソートした後の最新日付のデータ抽出時に、`filter`に与える関数をどう書けばいいか。)からは外れます。それゆえ、あくまでご参考に留めて頂ければと思います。
45
45
 
46
46
  配列やオブジェクトの操作で、便利なメソッドを提供しているライブラリ [Lodash](https://lodash.com/)に、 [_.groupBy](https://lodash.com/docs/#groupBy) というメソッドがあります。これを使うと配列の要素を何らかの値を基準にグルーピングしたオブジェクトを返してくれます。
47
47
 

15

テキスト修正

2019/09/01 00:17

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -41,7 +41,7 @@
41
41
 
42
42
  別解を挙げます。要所要所で便利なライブラリの力を借ります。
43
43
 
44
- ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、 `sort` するところから見直ますので、ご質問の本題(ご質問にあるコードで、`filter`の条件をどう書けばいいか。)からはやや外れます。あくまで参考に留めて頂ければと思います。
44
+ ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、その前の `sort` する処理含めて見直す案になりますので、ご質問の本題(ご質問にあるコードで、`filter`の条件をどう書けばいいか。)からは外れます。それゆえ、あくまで参考に留めて頂ければと思います。
45
45
 
46
46
  配列やオブジェクトの操作で、便利なメソッドを提供しているライブラリ [Lodash](https://lodash.com/)に、 [_.groupBy](https://lodash.com/docs/#groupBy) というメソッドがあります。これを使うと配列の要素を何らかの値を基準にグルーピングしたオブジェクトを返してくれます。
47
47
 

14

テキスト修正

2019/09/01 00:05

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -109,4 +109,4 @@
109
109
 
110
110
  - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)
111
111
 
112
- は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使追記2のコードの中間生成物としてMapを作のを省き、コード量を減らしたものです。
112
+ は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、中間生成物としてMapを作っていたのを省き、コード量を減らしたものです。

13

テキスト修正

2019/08/31 12:33

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -105,8 +105,8 @@
105
105
 
106
106
  ### 追記3
107
107
 
108
- 以下
108
+ 追記2 の修正版です。以下
109
109
 
110
- - [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)
110
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)
111
111
 
112
- は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、追記2のコードから中間Mapを作るのを省き、コード量を減らしたものです。
112
+ は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使、追記2のコード中間生成物として、Mapを作るのを省き、コード量を減らしたものです。

12

テキスト修正

2019/08/31 12:31

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -105,6 +105,8 @@
105
105
 
106
106
  ### 追記3
107
107
 
108
- 以下は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、追記2のコードから中間でMapを作るのを省き、コード量を減らしたものです。
108
+ 以下
109
109
 
110
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)
110
+ - [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)
111
+
112
+ は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、追記2のコードから中間でMapを作るのを省き、コード量を減らしたものです。

11

テキスト修正

2019/08/31 12:01

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -101,4 +101,10 @@
101
101
 
102
102
  上記のコードでは、 各キーに対して、日付が最新の要素(である配列)を取得するときに、Lodashの [_.maxBy](https://lodash.com/docs/#maxBy) も使っています。
103
103
 
104
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/12/](https://jsfiddle.net/jun68ykt/619atrpj/12/)
104
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/12/](https://jsfiddle.net/jun68ykt/619atrpj/12/)
105
+
106
+ ### 追記3
107
+
108
+ 以下は、 [_.map](https://lodash.com/docs/#map) と [_.sortBy](https://lodash.com/docs/#sortBy) を使って、追記2のコードから中間でMapを作るのを省き、コード量を減らしたものです。
109
+
110
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/nu9pfvhd/2/](https://jsfiddle.net/jun68ykt/nu9pfvhd/2/)

10

テキスト修正

2019/08/31 12:00

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -39,8 +39,10 @@
39
39
 
40
40
  ### 追記2
41
41
 
42
- 別解を挙げます。ただし、この別解は、ご質問に挙げられているコードの中、 `filter` する行だけではく、ソートするところから見直します。また、外部のライブラリの力を借りる案なので、ご質問の本題(ご質問にあるコードで、filterの条件をどう書けばいいか。)からはやや外れますから、あくまで参考に留めて頂ければと思います
42
+ 別解を挙げます。要所要所便利なライブラリの力を借ります。
43
43
 
44
+ ただし、こちらは、ご質問に挙げられているコードの `filter` する行だけではなく、 `sort` するところから見直しますので、ご質問の本題(ご質問にあるコードで、`filter`の条件をどう書けばいいか。)からはやや外れます。あくまで参考に留めて頂ければと思います。
45
+
44
46
  配列やオブジェクトの操作で、便利なメソッドを提供しているライブラリ [Lodash](https://lodash.com/)に、 [_.groupBy](https://lodash.com/docs/#groupBy) というメソッドがあります。これを使うと配列の要素を何らかの値を基準にグルーピングしたオブジェクトを返してくれます。
45
47
 
46
48
  このご質問の場合、カテゴリ1、カテゴリ2、カテゴリ3、それぞれの文字列を、たとえば `/` でjoinした文字列をその基準値に使ってグループ化することが考えられます。これは以下によって実現できます。
@@ -97,6 +99,6 @@
97
99
  .map(([_, v]) => v);
98
100
  ```
99
101
 
100
- 上記のコードでは、 各キーに対して、日付が最新の要素(である配列)を取得するときに、 [_.maxBy](https://lodash.com/docs/#maxBy) も使っています。
102
+ 上記のコードでは、 各キーに対して、日付が最新の要素(である配列)を取得するときに、Lodashの [_.maxBy](https://lodash.com/docs/#maxBy) も使っています。
101
103
 
102
104
  - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/12/](https://jsfiddle.net/jun68ykt/619atrpj/12/)

9

テキスト修正

2019/08/31 11:12

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -89,8 +89,7 @@
89
89
 
90
90
  // 各キーに対して、日付が最新の要素を値とするマップを作成
91
91
  var keyToNewestDateMap = groupedEntries.reduce(
92
- (map, [key, arrays]) => map.set(key, _.maxBy(arrays, ary => ary[4])
92
+ (map, [key, arrays]) => map.set(key, _.maxBy(arrays, ary => ary[4])), new Map());
93
- ), new Map());
94
93
 
95
94
  // 上記で作成したマップのエントリから、キー(カテゴリを / で連結した文字列)でソートされた、値の配列を取得
96
95
  var arr2 = [...keyToNewestDateMap]
@@ -100,4 +99,4 @@
100
99
 
101
100
  上記のコードでは、 各キーに対して、日付が最新の要素(である配列)を取得するときに、 [_.maxBy](https://lodash.com/docs/#maxBy) も使っています。
102
101
 
103
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/11/](https://jsfiddle.net/jun68ykt/619atrpj/11/)
102
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/12/](https://jsfiddle.net/jun68ykt/619atrpj/12/)

8

テキスト修正

2019/08/31 07:09

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -87,13 +87,10 @@
87
87
  // カテゴリ1,2,3をスラッシュを区切りとして連結した文字列をキーにグループ化したオブジェクトを得て、それのエントリ配列を取得
88
88
  var groupedEntries = Object.entries(_.groupBy(arr, ary => ary.slice(0,3).join('/')));
89
89
 
90
- // 各キーに対して、日付が最新の要素(である配列) を値とするマップを作成
90
+ // 各キーに対して、日付が最新の要素を値とするマップを作成
91
91
  var keyToNewestDateMap = groupedEntries.reduce(
92
- (map, [key, arrays]) =>
93
- map.set(
94
- key,
95
- arrays.sort((ary1, ary2) => ary2[4].localeCompare(ary1[4])).shift()
92
+ (map, [key, arrays]) => map.set(key, _.maxBy(arrays, ary => ary[4])
96
- ), new Map());
93
+ ), new Map());
97
94
 
98
95
  // 上記で作成したマップのエントリから、キー(カテゴリを / で連結した文字列)でソートされた、値の配列を取得
99
96
  var arr2 = [...keyToNewestDateMap]
@@ -101,4 +98,6 @@
101
98
  .map(([_, v]) => v);
102
99
  ```
103
100
 
101
+ 上記のコードでは、 各キーに対して、日付が最新の要素(である配列)を取得するときに、 [_.maxBy](https://lodash.com/docs/#maxBy) も使っています。
102
+
104
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/8/](https://jsfiddle.net/jun68ykt/619atrpj/8/)
103
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/11/](https://jsfiddle.net/jun68ykt/619atrpj/11/)

7

テキスト修正

2019/08/31 07:02

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -39,7 +39,7 @@
39
39
 
40
40
  ### 追記2
41
41
 
42
- 別解を挙げます。ただし、この別解は、ご質問に挙げられているコードの中で、 `filter` する行だけではなく、ソートするところから修正する案なので、ご質問の本題(filterの条件をどう書けばいいか。)はやや外れますので、あくまで参考に留めて頂ければと思います。
42
+ 別解を挙げます。ただし、この別解は、ご質問に挙げられているコードの中で、 `filter` する行だけではなく、ソートするところから見直しま。また、外部のライブラリの力を借りる案なので、ご質問の本題(ご質問にあるコードで、filterの条件をどう書けばいいか。)からはやや外れますから、あくまで参考に留めて頂ければと思います。
43
43
 
44
44
  配列やオブジェクトの操作で、便利なメソッドを提供しているライブラリ [Lodash](https://lodash.com/)に、 [_.groupBy](https://lodash.com/docs/#groupBy) というメソッドがあります。これを使うと配列の要素を何らかの値を基準にグルーピングしたオブジェクトを返してくれます。
45
45
 

6

テキスト修正

2019/08/31 06:26

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -85,10 +85,10 @@
85
85
 
86
86
  ```javascript
87
87
  // カテゴリ1,2,3をスラッシュを区切りとして連結した文字列をキーにグループ化したオブジェクトを得て、それのエントリ配列を取得
88
- var entries = Object.entries(_.groupBy(arr, ary => ary.slice(0,3).join('/')));
88
+ var groupedEntries = Object.entries(_.groupBy(arr, ary => ary.slice(0,3).join('/')));
89
89
 
90
90
  // 各キーに対して、日付が最新の要素(である配列) を値とするマップを作成
91
- var keyToNewestDateMap = entries.reduce(
91
+ var keyToNewestDateMap = groupedEntries.reduce(
92
92
  (map, [key, arrays]) =>
93
93
  map.set(
94
94
  key,
@@ -101,4 +101,4 @@
101
101
  .map(([_, v]) => v);
102
102
  ```
103
103
 
104
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/6/](https://jsfiddle.net/jun68ykt/619atrpj/6/)
104
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/8/](https://jsfiddle.net/jun68ykt/619atrpj/8/)

5

テキスト修正

2019/08/31 06:17

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  以上、参考になれば幸いです。
20
20
 
21
- ### 追記
21
+ ### 追記1
22
22
 
23
23
  質問への追記・修正のほうから、以下のご回答を頂きました。
24
24
 

4

テキスト修正

2019/08/31 05:53

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -35,4 +35,70 @@
35
35
  return x[0] !== y[0] || x[1] !== y[1] || x[2] !== y[2];
36
36
  ```
37
37
 
38
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/ao85qz0k/7/](https://jsfiddle.net/jun68ykt/ao85qz0k/7/)
38
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/ao85qz0k/7/](https://jsfiddle.net/jun68ykt/ao85qz0k/7/)
39
+
40
+ ### 追記2
41
+
42
+ 別解を挙げます。ただし、この別解は、ご質問に挙げられているコードの中で、 `filter` する行だけではなく、ソートするところから修正する案なので、ご質問の本題(filterの条件をどう書けばいいか。)とはやや外れますので、あくまで参考に留めて頂ければと思います。
43
+
44
+ 配列やオブジェクトの操作で、便利なメソッドを提供しているライブラリ [Lodash](https://lodash.com/)に、 [_.groupBy](https://lodash.com/docs/#groupBy) というメソッドがあります。これを使うと配列の要素を何らかの値を基準にグルーピングしたオブジェクトを返してくれます。
45
+
46
+ このご質問の場合、カテゴリ1、カテゴリ2、カテゴリ3、それぞれの文字列を、たとえば `/` でjoinした文字列をその基準値に使ってグループ化することが考えられます。これは以下によって実現できます。
47
+ ```javascript
48
+ _.groupBy(arr, ary => ary.slice(0,3).join('/'))
49
+ ```
50
+ 上記の _.groupBy が返すのは、下記のようなオブジェクトです。
51
+
52
+ ```javascript
53
+ {
54
+ "a/a/a":[
55
+ [ "a", "a", "a", 1, "2019/01/01" ],
56
+ [ "a", "a", "a", 1, "2019/02/02" ]
57
+ ],
58
+ "a/b/a":[
59
+ [ "a", "b", "a", 1, "2019/01/01" ]
60
+ ],
61
+ "b/a/a":[
62
+ [ "b", "a", "a", 1, "2019/01/01" ]
63
+ ],
64
+ "a/a/c":[
65
+ [ "a", "a", "c", 1, "2019/01/01" ]
66
+ ],
67
+ "c/a/c":[
68
+ [ "c", "a", "c", 1, "2019/01/01" ],
69
+ [ "c", "a", "c", 1, "2019/07/01" ]
70
+ ],
71
+ "b/b/b":[
72
+ [ "b", "b", "b", 1, "2019/01/01" ]
73
+ ],
74
+ "b/b/a":[
75
+ [ "b", "b", "a", 1, "2019/01/01" ]
76
+ ],
77
+ "b/a/b":[
78
+ [ "b", "a", "b", 1, "2019/01/01" ]
79
+ ]
80
+ }
81
+ ```
82
+ 上記のように、 各カテゴリの値 `a` や `b` を `/` を区切り文字として連結した文字列が、オブジェクトのキーになり、各キーに該当する要素(である配列)が配列としてまとめられます。なお上記では、`/` を連結時の区切り文字としていますが、各カテゴリの文字列それ自体の中にも `/` が出現する可能性があるのであれば、何か他の、各カテゴリの文字列の中には出現しない文字(列)で連結します。
83
+
84
+ 以下は、上記の _.groupBy を使って `arr` から `arr2` を得るコード例です。
85
+
86
+ ```javascript
87
+ // カテゴリ1,2,3をスラッシュを区切りとして連結した文字列をキーにグループ化したオブジェクトを得て、それのエントリ配列を取得
88
+ var entries = Object.entries(_.groupBy(arr, ary => ary.slice(0,3).join('/')));
89
+
90
+ // 各キーに対して、日付が最新の要素(である配列) を値とするマップを作成
91
+ var keyToNewestDateMap = entries.reduce(
92
+ (map, [key, arrays]) =>
93
+ map.set(
94
+ key,
95
+ arrays.sort((ary1, ary2) => ary2[4].localeCompare(ary1[4])).shift()
96
+ ), new Map());
97
+
98
+ // 上記で作成したマップのエントリから、キー(カテゴリを / で連結した文字列)でソートされた、値の配列を取得
99
+ var arr2 = [...keyToNewestDateMap]
100
+ .sort(([key1], [key2]) => key1.localeCompare(key2))
101
+ .map(([_, v]) => v);
102
+ ```
103
+
104
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/619atrpj/6/](https://jsfiddle.net/jun68ykt/619atrpj/6/)

3

テキスト修正

2019/08/31 05:51

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -35,6 +35,4 @@
35
35
  return x[0] !== y[0] || x[1] !== y[1] || x[2] !== y[2];
36
36
  ```
37
37
 
38
- - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/ao85qz0k/7/](https://jsfiddle.net/jun68ykt/ao85qz0k/7/)
38
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/ao85qz0k/7/](https://jsfiddle.net/jun68ykt/ao85qz0k/7/)
39
-
40
- ###

2

テキスト修正

2019/08/31 04:56

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -33,4 +33,8 @@
33
33
  **修正後:**
34
34
  ```javascript
35
35
  return x[0] !== y[0] || x[1] !== y[1] || x[2] !== y[2];
36
- ```
36
+ ```
37
+
38
+ - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/ao85qz0k/7/](https://jsfiddle.net/jun68ykt/ao85qz0k/7/)
39
+
40
+ ###

1

テキスト修正

2019/08/31 04:55

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -16,4 +16,21 @@
16
16
  - **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/ao85qz0k/2/](https://jsfiddle.net/jun68ykt/ao85qz0k/2/)
17
17
 
18
18
 
19
- 以上、参考になれば幸いです。
19
+ 以上、参考になれば幸いです。
20
+
21
+ ### 追記
22
+
23
+ 質問への追記・修正のほうから、以下のご回答を頂きました。
24
+
25
+ > カテゴリ値は二文字以上の文字列もあり得ます。
26
+
27
+ 上記に対応させるために、先に挙げたコードの `else` の場合の `return`文を、以下のように修正します。
28
+
29
+ **修正前:**
30
+ ```javascript
31
+ return `${x[0]}${x[1]}${x[2]}` !== `${y[0]}${y[1]}${y[2]}`;
32
+ ```
33
+ **修正後:**
34
+ ```javascript
35
+ return x[0] !== y[0] || x[1] !== y[1] || x[2] !== y[2];
36
+ ```