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

回答編集履歴

22

テキスト追加

2020/03/29 01:01

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  **1.**説明の便宜上、`data` の要素である配列(例: `["a","b",10]` )について、
10
10
   ・末尾の要素を除いた配列(例: `["a", "b"]` )を、**キー配列**と呼ぶ。
11
-  ・末尾の要素の数値(例: `10`) のことを、単に **数値** と呼ぶ。
11
+  ・末尾の要素(例: `10`) のことを、単に **数値** と呼ぶ。
12
12
 
13
13
  **2.**所与の `data` から、まず以下の2点を作成
14
14
   (ⅰ)`totals`:各キー配列別の数値の合計が格納されたオブジェクト

21

テキスト追加

2020/03/29 01:01

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -1,4 +1,9 @@
1
1
  すでにベストアンサーが決まった後に失礼します。
2
+
3
+
4
+ ### 考え方
5
+
6
+
2
7
  この回答では、考え方として以下の**1.**〜 **4. **の考え方によるアプローチを採ります。
3
8
 
4
9
  **1.**説明の便宜上、`data` の要素である配列(例: `["a","b",10]` )について、
@@ -18,8 +23,8 @@
18
23
 
19
24
  **4.**オブジェクト `totals` と `keys` から、結果として望ましい形式の配列 `result` を得る。
20
25
 
26
+ ### コード例
21
27
 
22
-
23
28
  以下は、上記の考え方によるコードです。配列やオブジェクトの操作で便利なライブラリ [lodash](https://lodash.com/) を使用しています。
24
29
 
25
30
  ```javascript

20

テキスト追加

2020/03/28 23:43

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -1,13 +1,25 @@
1
1
  すでにベストアンサーが決まった後に失礼します。
2
- この回答では、考え方として以下の1.〜 4. の考え方によるアプローチを採ります。
2
+ この回答では、考え方として以下の**1.****4. **の考え方によるアプローチを採ります。
3
3
 
4
+ **1.**説明の便宜上、`data` の要素である配列(例: `["a","b",10]` )について、
4
- 1. 説明の便宜上、`data` の要素である配列から、末尾の要素を除いた配列(例 `["a", "b"]`)を、**キー配列**と呼ぶ。
5
+  ・末尾の要素を除いた配列(例: `["a", "b"]` )を、**キー配列**と呼ぶ。
5
- 2. 所与の `data` から、まず以下の2点を作成
6
- (ⅰ)`totals`:合計値の情報が格納されたオブジェクト
7
- (ⅱ)`keys` `data` の要素に出現するキー配列を、出現順、かつ、**重複なく**含む配列
6
+  ・末尾の要素の数値(例: `10`)ことを、 **数値** と呼ぶ。
8
- 3. 上記2.(ⅰ)のオブジェクト `totals` には、キー配列が例えば `["a", "b"]` である`data`要素の末尾の数の合計(ご質問にあるサンプルだと **30**)が `totals.a.b` に格納されるようにする。
9
- 4. オブジェクト `totals` と `keys` から、結果として望ましい形式の配列 `result` を得る。
10
7
 
8
+ **2.**所与の `data` から、まず以下の2点を作成
9
+  (ⅰ)`totals`:各キー配列別の数値の合計が格納されたオブジェクト
10
+  (ⅱ)`keys` : `data` の要素に出現するキー配列を、出現順に、かつ、**重複なく**含む配列
11
+
12
+ **3.**上記2.(ⅰ)のオブジェクト `totals` には、キー配列が例えば `["a", "b"]` である数値の合計(ご質問にあるサンプルだと **30**)が `totals.a.b` に格納されるようにする。
13
+ ・従って、ご質問の例だと、 `totals` は以下のようなオブジェクトになる。
14
+ ```javascript
15
+ // totals の例
16
+ { a: { b: 30, c: 70, d: 50 } }
17
+ ```
18
+
19
+ **4.**オブジェクト `totals` と `keys` から、結果として望ましい形式の配列 `result` を得る。
20
+
21
+
22
+
11
23
  以下は、上記の考え方によるコードです。配列やオブジェクトの操作で便利なライブラリ [lodash](https://lodash.com/) を使用しています。
12
24
 
13
25
  ```javascript

19

テキスト追加

2020/03/28 23:40

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -1,12 +1,14 @@
1
1
  すでにベストアンサーが決まった後に失礼します。
2
- この回答では、考え方として以下のアプローチを採ります。
2
+ この回答では、考え方として以下の1.〜 4. の考え方によるアプローチを採ります。
3
3
 
4
+ 1. 説明の便宜上、`data` の要素である配列から、末尾の要素を除いた配列(例: `["a", "b"]`)を、**キー配列**と呼ぶ。
5
+ 2. 所与の `data` から、まず以下の2点を作成
4
- - 所与の `data` から、まず合計値の情報が格納されたオブジェクト `totals`を作る。
6
+ (ⅰ)`totals`合計値の情報が格納されたオブジェクト
7
+ (ⅱ)`keys` : `data` の要素に出現するキー配列を、出現順に、かつ、**重複なく**含む配列
5
- - オブジェクト `totals` には、末尾を除く要素たとえば `["a", "b"]` である配列の末尾の数の合計(ご質問にあるサンプルだと **30**)が `totals.a.b` に格納されるようにする。
8
+ 3. 上記2.(ⅰ)のオブジェクト `totals` には、キー配列えば `["a", "b"]` である`data`要素の末尾の数の合計(ご質問にあるサンプルだと **30**)が `totals.a.b` に格納されるようにする。
6
- - 上記を実現するために、[lodash](https://lodash.com/) を使用
7
- - オブジェクト `totals` から、結果として望ましい形式の配列 `result` を得る。
9
+ 4. オブジェクト `totals` と `keys` から、結果として望ましい形式の配列 `result` を得る。
8
10
 
9
- 以下は、上記の考え方によるコードです。
11
+ 以下は、上記の考え方によるコードです。配列やオブジェクトの操作で便利なライブラリ [lodash](https://lodash.com/) を使用しています。
10
12
 
11
13
  ```javascript
12
14
 
@@ -26,7 +28,7 @@
26
28
  ```
27
29
  上記のコードで使っている lodash のメソッドは以下です。
28
30
 
29
- - `totals`を作る際のキーに対する値の取得、設定および存在確認: [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has)
31
+ - `totals`のキー配列に対する値の取得、設定および存在確認: [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has)
30
32
  - 配列から最後の要素を取得: [_.last](https://lodash.com/docs/#last)
31
33
  - 配列から最後の要素を除いた配列の取得: [_.initial](https://lodash.com/docs/#initial)
32
34
 

18

テキスト追加

2020/03/28 22:53

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -1,12 +1,13 @@
1
1
  すでにベストアンサーが決まった後に失礼します。
2
- この回答では、考え方として
2
+ この回答では、考え方として以下のアプローチを採ります。
3
3
 
4
+ - 所与の `data` から、まず合計値の情報が格納されたオブジェクト `totals`を作る。
4
- - 末尾を除く要素がたとえば`["a", "b"]` である配列の末尾の数の合計(ご質問にあるサンプルだと **30**)が`totals.a.b` に格納されているようなオブジェクト`totals`を作り、そこから結果の配列を得る。
5
+ - オブジェクト `totals` には、末尾を除く要素がたとえば `["a", "b"]` である配列の末尾の数の合計(ご質問にあるサンプルだと **30**)が `totals.a.b` に格納されるようにする。
6
+ - 上記を実現するために、[lodash](https://lodash.com/) を使用
7
+ - オブジェクト `totals` から、結果として望ましい形式の配列 `result` を得る。
5
8
 
6
- という手順を踏みます。また、上記を実現するため、[lodash](https://lodash.com/) を使います。
9
+ 以下は、上記の考え方よるコードです。
7
10
 
8
-
9
- 以下は、上記の考え方によるコードです。
10
11
  ```javascript
11
12
 
12
13
  const [totals, keys] = data.reduce(([obj, keys], ary) => {

17

テキスト追加

2020/03/28 22:31

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -26,7 +26,7 @@
26
26
  上記のコードで使っている lodash のメソッドは以下です。
27
27
 
28
28
  - `totals`を作る際のキーに対する値の取得、設定および存在確認: [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has)
29
- - 配列最後の要素取得: [_.last](https://lodash.com/docs/#last)
29
+ - 配列から最後の要素取得: [_.last](https://lodash.com/docs/#last)
30
30
  - 配列から最後の要素を除いた配列の取得: [_.initial](https://lodash.com/docs/#initial)
31
31
 
32
32
 

16

テキスト追加

2020/03/28 02:44

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -3,12 +3,9 @@
3
3
 
4
4
  - 末尾を除く要素がたとえば、`["a", "b"]` である配列の末尾の数の合計値(ご質問にあるサンプルだと **30**)が、 `totals.a.b` に格納されているようなオブジェクト`totals`を作り、そこから結果の配列を得る。
5
5
 
6
- という手順を踏みます。
6
+ という手順を踏みます。また、上記を実現するために、[lodash](https://lodash.com/) を使います。
7
7
 
8
- [lodash](https://lodash.com/) を使うコードを回答します。
9
8
 
10
- 具体的には、
11
-
12
9
  以下は、上記の考え方によるコードです。
13
10
  ```javascript
14
11
 

15

テキスト追加

2020/03/28 02:11

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -1,15 +1,14 @@
1
1
  すでにベストアンサーが決まった後に失礼します。
2
+ この回答では、考え方として
2
3
 
3
- [lodash](https://lodash.com/) を使うコードを回答します。具体的以下のような手順で結果を得ます
4
+ - 末尾を除く要素がたとえば、`["a", "b"]` である配列の末尾の数の合計値(ご質問あるサンプルだと **30**)が `totals.a.b` に格納されているようなオブジェクト`totals`を作り、そこから結果の配列を得
4
5
 
5
- - 末尾を除く要素がたとえば、`["a", "b"]` である配列の末尾の数の合計値(ご質問にあるサンプルだと **30**)が、 `totals.a.b` に格納されているようなオブジェクト`totals`を作り、そこから結果の配列を得ます。
6
- - 上記の `totals`を作るために、 [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使います。
7
- - また、配列の最後の要素の取得に [_.last](https://lodash.com/docs/#last) を、
8
- - 最後の要素を除た配列得るために [_.initial](https://lodash.com/docs/#initial) を使います。
6
+ う手順踏みます。
9
-  
10
7
 
11
-  
8
+ [lodash](https://lodash.com/) を使うコードを回答します。
12
9
 
10
+ 具体的には、
11
+
13
12
  以下は、上記の考え方によるコードです。
14
13
  ```javascript
15
14
 
@@ -26,10 +25,23 @@
26
25
  }, [{}, []]);
27
26
 
28
27
  const result = keys.map(k => [...k, _.get(totals, k)]);
28
+ ```
29
+ 上記のコードで使っている lodash のメソッドは以下です。
29
30
 
31
+ - `totals`を作る際のキーに対する値の取得、設定および存在確認: [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has)
32
+ - 配列の最後の要素の取得: [_.last](https://lodash.com/docs/#last)
33
+ - 配列から最後の要素を除いた配列の取得: [_.initial](https://lodash.com/docs/#initial)
30
34
 
31
- ```
32
35
 
36
+
37
+  
38
+
39
+  
40
+
41
+
33
42
  以下は、上記のコードを動作確認するためのサンプルです。動作確認のため、`data`に要素を追加しています。
34
43
 
35
- - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012](https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012)
44
+ - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012](https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012)
45
+
46
+
47
+ 以上、参考になれば幸いです。

14

テキスト追加

2020/03/28 02:10

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [lodash](https://lodash.com/) を使うコードを回答します。具体的には、以下のような手順で結果を得ます。
4
4
 
5
- - たとえば、先頭要素が`["a", "b"]` である配列の末尾の数の合計値(ご質問にあるサンプルだと **30**)が、 `totals.a.b` に格納されているようなオブジェクト`totals`を作り、そこから結果の配列を得ます。
5
+ - 末尾を除く要素がたとえば、`["a", "b"]` である配列の末尾の数の合計値(ご質問にあるサンプルだと **30**)が、 `totals.a.b` に格納されているようなオブジェクト`totals`を作り、そこから結果の配列を得ます。
6
6
  - 上記の `totals`を作るために、 [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使います。
7
7
  - また、配列の最後の要素の取得に [_.last](https://lodash.com/docs/#last) を、
8
8
  - 最後の要素を除いた配列を得るために [_.initial](https://lodash.com/docs/#initial) を使います。

13

テキスト追加

2020/03/28 01:57

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -1,96 +1,16 @@
1
1
  すでにベストアンサーが決まった後に失礼します。
2
2
 
3
+ [lodash](https://lodash.com/) を使うコードを回答します。具体的には、以下のような手順で結果を得ます。
3
4
 
4
- [lodash](https://lodash.com/) を使うコードを回答します。使うのは、 [_.groupBy](https://lodash.com/docs/#groupBy) と [_.mapValues](https://lodash.com/docs/#mapValues) です。
5
-
6
- ### 1.グループ化したオブジェクトを得る
7
-
8
- `data` の要素である配列を、合計する配列ごとにグループ化したオブジェクトを作ります。オブジェクトのキーとなる文字列としてJSONを採用することにして、キーを得る関数 `key` を以下のように作っておきます。
9
-
10
- ```javascript
11
- const key = ary => JSON.stringify(ary.slice(0, 2));
12
- ```
13
-
14
- たとえば、`key(["a", "b", 10])` は、配列 **["a", "b"]** をJSONにした、`["a","b"]`という文字列を返します。
15
-
16
- 上記の `key` を使って、グループ化したオブジェクトは以下によって得られます。
17
-
18
- ```javascript
19
- const objGroups = _.groupBy(data, key);
20
- ```
21
- 得られる`objGroups` の内容は、以下のようなものになります。
22
- ```
23
- {
24
- '["a","b"]': [["a", "b", 10], ["a", "b", 20]],
25
- '["a","c"]': [["a", "c", 30], ["a", "c", 40]],
26
- '["a","d"]': [["a", "c", 50]],
27
- }
28
- ```
29
-
30
- ### 2. 各グループごとの合計を計算する
31
-
32
- 上記の 1. で得られたオブジェクト `objGroups` から、各キーごとにグループ化された配列の第3要素の合計が値となるようなオブジェクト `objTotals` を作ります。
33
-
34
- 合計を計算する補助的な関数を以下のように作っておきます。
35
-
36
- ```javascript
37
- const totalize = data => data.reduce((total, ary) => total + ary[2], 0);
38
- ```
39
-
40
- 上記の `totalize` を、 [_.mapValues](https://lodash.com/docs/#mapValues) の第2引数に使うことで、以下によって `objTotals` が得られます。
41
- ```javascript
42
- const objTotals = _.mapValues(objGroups, totalize);
43
- ```
44
-
45
- 得られる`objTotals` の内容は、以下のようなものになります。
46
- ```
47
- {
48
- '["a","b"]': 30,
49
- '["a","c"]': 70,
50
- '["a","d"]': 50
51
- }
52
- ```
53
-
54
-
55
- ### 3. 結果として望ましい形の配列を得る
56
-
57
- 上記 2. で得られた `objTotals` を、最終的に得たい形の配列にします。その際に、キーをJSONから配列に戻すのと、オブジェクトを経由しているので、ソートして結果を得るようにします。
58
-
59
- まず、ソートで使う比較関数を以下のように用意しておきます。
60
-
61
- ```javascript
62
- const compare = (a, b) => a[0].localeCompare(b[0]) || a[1].localeCompare(b[1]);
63
- ```
64
-
65
- 上記の `compare` 使って、最終的に得たい配列 `result` は、以下によって得られます。
66
-
67
- ```javascript
68
- const result = Object.entries(objTotals)
69
- .map(([key, total]) => [...JSON.parse(key), total])
70
- .sort(compare);
71
- ```
72
- ```
73
- [ ["a","b",30], ["a","c",70], ["a","d",50] ]
74
- ```
75
-
76
-   
77
-   
78
-  
79
- - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/QWbzGbd?editors=0012](https://codepen.io/jun68ykt/pen/QWbzGbd?editors=0012)
80
-
81
-
82
- 参考になれば幸いです。
83
-
84
-
85
- ### 別解
86
-
87
- 同じく lodash を使った例です。
88
- こちらは、
89
- - 先頭要素が`["a", "b"]` である配列の末尾の数の合計値 30 が `totals.a.b` で得られるようなオブジェクト `totals`を作り、そこから結果の配列を得ます。
5
+ - たとえば、先頭要素が`["a", "b"]` である配列の末尾の数の合計値(ご質問にあるサンプルだと **30**) `totals.a.b` に格納さているようなオブジェクト`totals`を作り、そこから結果の配列を得ます。
90
6
  - 上記の `totals`を作るために、 [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使います。
91
7
  - また、配列の最後の要素の取得に [_.last](https://lodash.com/docs/#last) を、
92
8
  - 最後の要素を除いた配列を得るために [_.initial](https://lodash.com/docs/#initial) を使います。
9
+  
93
10
 
11
+  
12
+
13
+ 以下は、上記の考え方によるコードです。
94
14
  ```javascript
95
15
 
96
16
  const [totals, keys] = data.reduce(([obj, keys], ary) => {
@@ -99,8 +19,8 @@
99
19
  _.set(obj, k, _.get(obj, k) + v);
100
20
  }
101
21
  else {
22
+ _.set(obj, k, v);
102
23
  keys.push(k);
103
- _.set(obj, k, v);
104
24
  }
105
25
  return [obj, keys];
106
26
  }, [{}, []]);
@@ -110,4 +30,6 @@
110
30
 
111
31
  ```
112
32
 
33
+ 以下は、上記のコードを動作確認するためのサンプルです。動作確認のため、`data`に要素を追加しています。
34
+
113
35
  - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012](https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012)

12

テキスト追加

2020/03/28 01:52

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -5,10 +5,10 @@
5
5
 
6
6
  ### 1.グループ化したオブジェクトを得る
7
7
 
8
- `data` の要素である配列を、合計するものごとにグループ化したオブジェクトを作ります。まず、このオブジェクトのキーとなる文字列をる関数を以下のように作っておきます。
8
+ `data` の要素である配列を、合計する配列ごとにグループ化したオブジェクトを作ります。オブジェクトのキーとなる文字列としてJSON採用すことにして、キーを得る関数 `key` を以下のように作っておきます。
9
9
 
10
10
  ```javascript
11
- const key = (ary) => JSON.stringify(ary.slice(0, 2));
11
+ const key = ary => JSON.stringify(ary.slice(0, 2));
12
12
  ```
13
13
 
14
14
  たとえば、`key(["a", "b", 10])` は、配列 **["a", "b"]** をJSONにした、`["a","b"]`という文字列を返します。

11

テキスト追加

2020/03/28 01:17

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -86,7 +86,7 @@
86
86
 
87
87
  同じく lodash を使った例です。
88
88
  こちらは、
89
- - `["a", "b"]` の合計値が `totals.a.b` で得られるようなオブジェクト `totals`を作り、そこから結果の配列を得ます。
89
+ - 先頭要素が`["a", "b"]` である配列末尾の数の合計値 30 が `totals.a.b` で得られるようなオブジェクト `totals`を作り、そこから結果の配列を得ます。
90
90
  - 上記の `totals`を作るために、 [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使います。
91
91
  - また、配列の最後の要素の取得に [_.last](https://lodash.com/docs/#last) を、
92
92
  - 最後の要素を除いた配列を得るために [_.initial](https://lodash.com/docs/#initial) を使います。

10

テキスト追加

2020/03/28 01:03

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -89,7 +89,7 @@
89
89
  - `["a", "b"]` の合計値が `totals.a.b` で得られるようなオブジェクト `totals`を作り、そこから結果の配列を得ます。
90
90
  - 上記の `totals`を作るために、 [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使います。
91
91
  - また、配列の最後の要素の取得に [_.last](https://lodash.com/docs/#last) を、
92
- - 最後の要素を除配列を得るために [_.initial](https://lodash.com/docs/#initial) を使います。
92
+ - 最後の要素を除いた配列を得るために [_.initial](https://lodash.com/docs/#initial) を使います。
93
93
 
94
94
  ```javascript
95
95
 

9

テキスト追加

2020/03/28 01:00

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -105,7 +105,7 @@
105
105
  return [obj, keys];
106
106
  }, [{}, []]);
107
107
 
108
- const result = keys.map(key => [...k, _.get(totals, k)]);
108
+ const result = keys.map(k => [...k, _.get(totals, k)]);
109
109
 
110
110
 
111
111
  ```

8

テキスト追加

2020/03/28 00:59

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -84,7 +84,12 @@
84
84
 
85
85
  ### 別解
86
86
 
87
- 同じく lodash を使った例です。こちらは [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使って、 `["a", "b"]` の合計値が `totals.a.b` で得られるようなオブジェクト `totals`を作り、そこから結果の配列を得ます。また、配列の最後の要素の取得には、[_.last](https://lodash.com/docs/#last)、最後の要素を除く配列を得るために、[_.initial](https://lodash.com/docs/#initial) を使います。
87
+ 同じく lodash を使った例です。
88
+ こちらは、
89
+ - `["a", "b"]` の合計値が `totals.a.b` で得られるようなオブジェクト `totals`を作り、そこから結果の配列を得ます。
90
+ - 上記の `totals`を作るために、 [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使います。
91
+ - また、配列の最後の要素の取得に [_.last](https://lodash.com/docs/#last) を、
92
+ - 最後の要素を除く配列を得るために [_.initial](https://lodash.com/docs/#initial) を使います。
88
93
 
89
94
  ```javascript
90
95
 
@@ -100,7 +105,7 @@
100
105
  return [obj, keys];
101
106
  }, [{}, []]);
102
107
 
103
- const result = keys.map(key => [...key, _.get(totals, key)]);
108
+ const result = keys.map(key => [...k, _.get(totals, k)]);
104
109
 
105
110
 
106
111
  ```

7

テキスト追加

2020/03/28 00:58

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -88,7 +88,7 @@
88
88
 
89
89
  ```javascript
90
90
 
91
- const [obj, keys] = data.reduce(([obj, keys], ary) => {
91
+ const [totals, keys] = data.reduce(([obj, keys], ary) => {
92
92
  const [k, v] = [_.initial(ary), _.last(ary)];
93
93
  if (_.has(obj, k)) {
94
94
  _.set(obj, k, _.get(obj, k) + v);
@@ -100,8 +100,9 @@
100
100
  return [obj, keys];
101
101
  }, [{}, []]);
102
102
 
103
- const result = keys.map(key => [...key, _.get(obj, key)]);
103
+ const result = keys.map(key => [...key, _.get(totals, key)]);
104
104
 
105
+
105
106
  ```
106
107
 
107
108
  - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012](https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012)

6

テキスト追加

2020/03/28 00:49

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -84,12 +84,12 @@
84
84
 
85
85
  ### 別解
86
86
 
87
- 同じく lodash を使った例です。こちらは [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使って、 `["a", "b"]` の合計値が `totals.a.b` で得られるようなオブジェクト `totals`を作り、そこから結果の配列を得ます。
87
+ 同じく lodash を使った例です。こちらは [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使って、 `["a", "b"]` の合計値が `totals.a.b` で得られるようなオブジェクト `totals`を作り、そこから結果の配列を得ます。また、配列の最後の要素の取得には、[_.last](https://lodash.com/docs/#last)、最後の要素を除く配列を得るために、[_.initial](https://lodash.com/docs/#initial) を使います。
88
88
 
89
89
  ```javascript
90
90
 
91
91
  const [obj, keys] = data.reduce(([obj, keys], ary) => {
92
- const [k, v] = [ary.slice(0, ary.length-1), ary[ary.length-1]];
92
+ const [k, v] = [_.initial(ary), _.last(ary)];
93
93
  if (_.has(obj, k)) {
94
94
  _.set(obj, k, _.get(obj, k) + v);
95
95
  }

5

テキスト追加

2020/03/28 00:47

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -84,7 +84,7 @@
84
84
 
85
85
  ### 別解
86
86
 
87
- 同じく lodash を使った例です。こちらは [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使って、 `["a", "b"]` の合計値が `obj.a.b` で得られるようなオブジェクト `obj`を作り、そこから結果の配列を得ます。
87
+ 同じく lodash を使った例です。こちらは [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使って、 `["a", "b"]` の合計値が `totals.a.b` で得られるようなオブジェクト `totals`を作り、そこから結果の配列を得ます。
88
88
 
89
89
  ```javascript
90
90
 

4

テキスト追加

2020/03/28 00:38

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -89,8 +89,7 @@
89
89
  ```javascript
90
90
 
91
91
  const [obj, keys] = data.reduce(([obj, keys], ary) => {
92
- const k = ary.slice(0, ary.length-1),
92
+ const [k, v] = [ary.slice(0, ary.length-1), ary[ary.length-1]];
93
- v = ary[ary.length-1];
94
93
  if (_.has(obj, k)) {
95
94
  _.set(obj, k, _.get(obj, k) + v);
96
95
  }

3

テキスト追加

2020/03/28 00:26

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -84,38 +84,25 @@
84
84
 
85
85
  ### 別解
86
86
 
87
- JavaScript標準のMapではなく、[immutable-js](https://immutable-js.github.io/immutable-js/) [Map](https://immutable-js.github.io/immutable-js/docs/#/Map) を使ます。
87
+ 同じく lodash を使った例す。こちら [_.get](https://lodash.com/docs/#get), [_.set](https://lodash.com/docs/#set), [_.has](https://lodash.com/docs/#has) を使って、 `["a", "b"]` の合計値が、 `obj.a.b` で得られるようなオブジェクト `obj`を作り、そこから結果の配列を得ます。
88
88
 
89
89
  ```javascript
90
90
 
91
- const { Map } = Immutable;
92
-
93
- const data = [
94
- ["a","b",10], ["x", "y", "z", 100], ["a","c",30],
95
- ["a","b",20], ["a","c",40], ["x", "y", "z", 200],
96
- ["a","d",50]
97
- ];
98
-
99
- const [map, keys] = data.reduce(([m, keys], ary) => {
91
+ const [obj, keys] = data.reduce(([obj, keys], ary) => {
100
92
  const k = ary.slice(0, ary.length-1),
101
93
  v = ary[ary.length-1];
102
- if (m.hasIn(k)) {
94
+ if (_.has(obj, k)) {
103
- m = m.setIn(k, m.getIn(k) + v);
95
+ _.set(obj, k, _.get(obj, k) + v);
104
96
  }
105
97
  else {
106
98
  keys.push(k);
107
- m = m.setIn(k, v);
99
+ _.set(obj, k, v);
108
100
  }
109
- return [m, keys];
101
+ return [obj, keys];
110
- }, [Map(), []]);
102
+ }, [{}, []]);
111
103
 
112
- const result = keys.map(key => [...key, map.getIn(key)]);
104
+ const result = keys.map(key => [...key, _.get(obj, key)]);
113
105
 
114
106
  ```
115
- 上記によって`result`には、以下が得られます。
116
107
 
117
- ```
118
- [ ["a","b",30], ["x", "y", "z", 300], ["a","c",70], ["a","d",50] ]
119
- ```
120
-
121
- - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/wvaRdPg?editors=0012](https://codepen.io/jun68ykt/pen/wvaRdPg?editors=0012)
108
+ - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012](https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012)

2

テキスト追加

2020/03/27 20:57

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -96,45 +96,26 @@
96
96
  ["a","d",50]
97
97
  ];
98
98
 
99
- const obj = data.reduce((m, ary) => {
99
+ const [map, keys] = data.reduce(([m, keys], ary) => {
100
- const key = ary.slice(0, ary.length-1);
100
+ const k = ary.slice(0, ary.length-1),
101
- const value = ary[ary.length-1];
101
+ v = ary[ary.length-1];
102
+ if (m.hasIn(k)) {
102
- return m.setIn(key, (m.getIn(key) || 0) + value);
103
+ m = m.setIn(k, m.getIn(k) + v);
104
+ }
105
+ else {
106
+ keys.push(k);
107
+ m = m.setIn(k, v);
108
+ }
109
+ return [m, keys];
103
- }, Map()).toJS();
110
+ }, [Map(), []]);
104
111
 
112
+ const result = keys.map(key => [...key, map.getIn(key)]);
105
113
 
106
114
  ```
115
+ 上記によって`result`には、以下が得られます。
107
116
 
108
- 上記によって、`obj`には、下記のようなオブジェクトが得られます。
109
117
  ```
110
- { a: { b: 30, c: 70, d: 50 }, x: { y: { z: 300 }}}
118
+ [ ["a","b",30], ["x", "y", "z", 300], ["a","c",70], ["a","d",50] ]
111
119
  ```
112
120
 
113
- 上記のオブジェクトから、結果として得たい配列を作る再帰関数 `getEntries` を、以下
114
- ```javascript
115
- const getEntries = (obj, path, result) => {
116
- if (!path) path = [];
117
- if (!result) result = [];
118
-
119
- Object.entries(obj).forEach(([k, v]) => {
120
- if (typeof v === 'number') {
121
- result.push([...path, k, v]);
122
- } else {
123
- getEntries(v, [...path, k], result);
124
- }
125
- })
126
- return result;
127
- }
128
- ```
129
- のように作成しておいて、
130
-
131
- ```javascript
132
- const result = getEntries(obj);
133
- ```
134
- とすると、`result`には、以下が得られます。
135
-
136
- ```
137
- [ ["a","b",30], ["a","c",70], ["a","d",50], ["x", "y", "z", 300] ]
138
- ```
139
-
140
- - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/dyowNjW?editors=0012](https://codepen.io/jun68ykt/pen/dyowNjW?editors=0012)
121
+ - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/wvaRdPg?editors=0012](https://codepen.io/jun68ykt/pen/wvaRdPg?editors=0012)

1

テキスト追加

2020/03/27 20:41

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -79,4 +79,62 @@
79
79
  - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/QWbzGbd?editors=0012](https://codepen.io/jun68ykt/pen/QWbzGbd?editors=0012)
80
80
 
81
81
 
82
- 参考になれば幸いです。
82
+ 参考になれば幸いです。
83
+
84
+
85
+ ### 別解
86
+
87
+ JavaScript標準のMapではなく、[immutable-js](https://immutable-js.github.io/immutable-js/) の [Map](https://immutable-js.github.io/immutable-js/docs/#/Map) を使います。
88
+
89
+ ```javascript
90
+
91
+ const { Map } = Immutable;
92
+
93
+ const data = [
94
+ ["a","b",10], ["x", "y", "z", 100], ["a","c",30],
95
+ ["a","b",20], ["a","c",40], ["x", "y", "z", 200],
96
+ ["a","d",50]
97
+ ];
98
+
99
+ const obj = data.reduce((m, ary) => {
100
+ const key = ary.slice(0, ary.length-1);
101
+ const value = ary[ary.length-1];
102
+ return m.setIn(key, (m.getIn(key) || 0) + value);
103
+ }, Map()).toJS();
104
+
105
+
106
+ ```
107
+
108
+ 上記によって、`obj`には、下記のようなオブジェクトが得られます。
109
+ ```
110
+ { a: { b: 30, c: 70, d: 50 }, x: { y: { z: 300 }}}
111
+ ```
112
+
113
+ 上記のオブジェクトから、結果として得たい配列を作る再帰関数 `getEntries` を、以下
114
+ ```javascript
115
+ const getEntries = (obj, path, result) => {
116
+ if (!path) path = [];
117
+ if (!result) result = [];
118
+
119
+ Object.entries(obj).forEach(([k, v]) => {
120
+ if (typeof v === 'number') {
121
+ result.push([...path, k, v]);
122
+ } else {
123
+ getEntries(v, [...path, k], result);
124
+ }
125
+ })
126
+ return result;
127
+ }
128
+ ```
129
+ のように作成しておいて、
130
+
131
+ ```javascript
132
+ const result = getEntries(obj);
133
+ ```
134
+ とすると、`result`には、以下が得られます。
135
+
136
+ ```
137
+ [ ["a","b",30], ["a","c",70], ["a","d",50], ["x", "y", "z", 300] ]
138
+ ```
139
+
140
+ - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/dyowNjW?editors=0012](https://codepen.io/jun68ykt/pen/dyowNjW?editors=0012)