回答編集履歴
12
テキスト修正
answer
CHANGED
@@ -200,4 +200,24 @@
|
|
200
200
|
|
201
201
|
- C-10 の親は B-2 で、B-2 の親は A-2
|
202
202
|
|
203
|
-
となってしまい、B-2 には、二つの親、A-1 と A-2 があることになってしまいます。ですが、先のstackoverflow の投稿では、各ノードの親は、木構造の定義に沿って、(最大で)一個であるようなノードの一次元配列を木構造化するコードでした。これを踏まえて、それでも[ベストアンサー](https://stackoverflow.com/a/18018037) の `function list_to_tree(list)` を使おうとすると、id として A-1やB-2だったりの文字列はそのまま使えず、「A-1 が親のB-1 と、A-2が親のB-2とは、別物である」という考え方を採り入れて、それらに異なる id を設ける必要があり、これはけっこう煩雑な作業となりそうです。
|
203
|
+
となってしまい、B-2 には、二つの親、A-1 と A-2 があることになってしまいます。ですが、先のstackoverflow の投稿では、各ノードの親は、木構造の定義に沿って、(最大で)一個であるようなノードの一次元配列を木構造化するコードでした。これを踏まえて、それでも[ベストアンサー](https://stackoverflow.com/a/18018037) の `function list_to_tree(list)` を使おうとすると、id として A-1やB-2だったりの文字列はそのまま使えず、「A-1 が親のB-1 と、A-2が親のB-2とは、別物である」という考え方を採り入れて、それらに異なる id を設ける必要があり、これはけっこう煩雑な作業となりそうです。
|
204
|
+
|
205
|
+
### 追記4
|
206
|
+
|
207
|
+
上記の追記3で書いた、[function list_to_tree(list)](https://stackoverflow.com/a/18018037) を使うための
|
208
|
+
|
209
|
+
> 「A-1 が親のB-1 と、A-2が親のB-2とは、別物である」という考え方を採り入れて、それらに異なる id
|
210
|
+
|
211
|
+
を実装したコード例を挙げておきます。以下になります。(※ `list_to_tree(list)` は、そのままコピペしてきたもので、手を加えていません)
|
212
|
+
|
213
|
+
- **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/zYrNQzv?editors=0012](https://codepen.io/jun68ykt/pen/zYrNQzv?editors=0012)
|
214
|
+
|
215
|
+
具体的には、たとえば、`[ 'A-2', 'B-2', 'C-10' ]` の `C-10` から、以下のようなノードオブジェクトを作成します。
|
216
|
+
```javascript
|
217
|
+
{ id: 'A-2/B-2/C-10', parentId: 'A-2/B-2', label: 'C-10' }
|
218
|
+
```
|
219
|
+
また、トップレベルの `A-2` からは、 parentId に文字列の `"0"` を入れた、以下のオブジェクトを作成します。
|
220
|
+
```javascript
|
221
|
+
{ id: 'A-2', parentId: '0', label: 'A-2' }
|
222
|
+
```
|
223
|
+
上記のようなオブジェクトを要素とする一次元配列を、元のテーブルデータから作成すると、その配列を [function list_to_tree(list)](https://stackoverflow.com/a/18018037) に渡すことができて、木構造化した配列を返してくれますので、それをさらに望ましい形にフォーマットして結果を得ています。
|
11
テキスト修正
answer
CHANGED
@@ -170,4 +170,34 @@
|
|
170
170
|
console.log(JSON.stringify(treeArray, null, 2));
|
171
171
|
```
|
172
172
|
|
173
|
-
- **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/oNbBaKE?editors=0012](https://codepen.io/jun68ykt/pen/oNbBaKE?editors=0012)
|
173
|
+
- **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/oNbBaKE?editors=0012](https://codepen.io/jun68ykt/pen/oNbBaKE?editors=0012)
|
174
|
+
|
175
|
+
### 追記3
|
176
|
+
|
177
|
+
先に書いた、追記1 で、stackoverflow の投稿 [Build tree array from flat array in javascript](https://stackoverflow.com/questions/18017869) を挙げましたが、これの回答の中の[ベストアンサー](https://stackoverflow.com/a/18018037) の `function list_to_tree(list)` を使えそうか、ちょっとスパイクしてみましたが、問題があり簡単にはできそうもなかったです。その説明を以下、記載します。
|
178
|
+
|
179
|
+
元のテーブルのデータ配列は
|
180
|
+
```
|
181
|
+
[
|
182
|
+
[ '列A', '列B', '列C' ],
|
183
|
+
[ 'A-1', 'B-1', 'C-1' ],
|
184
|
+
[ 'A-1', 'B-1', 'C-2' ],
|
185
|
+
[ 'A-1', 'B-2', 'C-3' ],
|
186
|
+
[ 'A-1', 'B-2', 'C-4' ],
|
187
|
+
[ 'A-2', 'B-3', 'C-5' ],
|
188
|
+
[ 'A-2', 'B-3', 'C-6' ],
|
189
|
+
[ 'A-2', 'B-4', 'C-7' ],
|
190
|
+
[ 'A-2', 'B-4', 'C-8' ],
|
191
|
+
[ 'A-1', 'B-5', 'C-9' ],
|
192
|
+
[ 'A-2', 'B-2', 'C-10' ]
|
193
|
+
]
|
194
|
+
```
|
195
|
+
というものですが、これのデータ行の3行目 `[ 'A-1', 'B-2', 'C-3' ]` を、ツリー末端の子(葉)のほうから親のほうへ向かうパスとして読むと
|
196
|
+
|
197
|
+
- C-3 の親は B-2 で、B-2 の親は A-1
|
198
|
+
|
199
|
+
と読めるのですが、そうすると、最後の行の `[ 'A-2', 'B-2', 'C-10' ]` は
|
200
|
+
|
201
|
+
- C-10 の親は B-2 で、B-2 の親は A-2
|
202
|
+
|
203
|
+
となってしまい、B-2 には、二つの親、A-1 と A-2 があることになってしまいます。ですが、先のstackoverflow の投稿では、各ノードの親は、木構造の定義に沿って、(最大で)一個であるようなノードの一次元配列を木構造化するコードでした。これを踏まえて、それでも[ベストアンサー](https://stackoverflow.com/a/18018037) の `function list_to_tree(list)` を使おうとすると、id として A-1やB-2だったりの文字列はそのまま使えず、「A-1 が親のB-1 と、A-2が親のB-2とは、別物である」という考え方を採り入れて、それらに異なる id を設ける必要があり、これはけっこう煩雑な作業となりそうです。
|
10
テキスト修正
answer
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
こんにちは
|
2
2
|
|
3
|
-
いろいろなやり方がありそうですが、一例を回答します。以下の二次元配列 `tableData` から目的のJSONを得るコードを挙げます
|
3
|
+
いろいろなやり方がありそうですが、一例を回答します。以下の二次元配列 `tableData` から目的のJSONを得るコードを挙げます。
|
4
4
|
```javascript
|
5
5
|
const tableData = [
|
6
6
|
[ '列A', '列B', '列C' ],
|
@@ -16,7 +16,7 @@
|
|
16
16
|
[ 'A-2', 'B-2', 'C-10' ]
|
17
17
|
];
|
18
18
|
```
|
19
|
-
上記の配列`tableData`から、階層構造を復元したオブジェクトを作ります。その際に lodash の [_.set](https://lodash.com/docs/#set)を使います。
|
19
|
+
上記の配列`tableData`から、階層構造を復元したオブジェクトを作ります。その際に lodash の [_.set](https://lodash.com/docs/#set) を使います。
|
20
20
|
|
21
21
|
```javascript
|
22
22
|
const treeObj = tableData.slice(1).reduce((obj, path) => _(obj).set(path, null).value(), {});
|
@@ -134,7 +134,7 @@
|
|
134
134
|
以上参考になれば幸いです。
|
135
135
|
|
136
136
|
|
137
|
-
### 追記
|
137
|
+
### 追記1
|
138
138
|
|
139
139
|
別案を検討する際の参考情報です。一次元のオブジェクト配列から、オブジェクト間の階層構造を復元した配列に変換するコードの例は
|
140
140
|
|
9
テキスト修正
answer
CHANGED
@@ -165,7 +165,7 @@
|
|
165
165
|
return treeArray;
|
166
166
|
};
|
167
167
|
|
168
|
-
const treeArray = tableData.slice(1).reduce((
|
168
|
+
const treeArray = tableData.slice(1).reduce((tree, row) => addRowToTree(tree, row), []);
|
169
169
|
|
170
170
|
console.log(JSON.stringify(treeArray, null, 2));
|
171
171
|
```
|
8
テキスト修正
answer
CHANGED
@@ -148,18 +148,18 @@
|
|
148
148
|
|
149
149
|
```javascript
|
150
150
|
const addRowToTree = (treeArray, row) => {
|
151
|
-
let
|
151
|
+
let list = treeArray;
|
152
152
|
for (let i=0; i < row.length; ++ i) {
|
153
153
|
if (i < row.length-1) {
|
154
154
|
const key = `列${row[i][0]}`;
|
155
|
-
let obj =
|
155
|
+
let obj = list.find(e => e[key] === row[i]);
|
156
156
|
if (!obj) {
|
157
157
|
obj = { [key]: row[i], list: [] };
|
158
|
-
|
158
|
+
list.push(obj);
|
159
159
|
}
|
160
|
-
|
160
|
+
list = obj.list;
|
161
161
|
} else {
|
162
|
-
|
162
|
+
list.push(row[i]);
|
163
163
|
}
|
164
164
|
}
|
165
165
|
return treeArray;
|
7
テキスト修正
answer
CHANGED
@@ -147,7 +147,7 @@
|
|
147
147
|
オブジェクトを経由しない別案を作成しました。こちらは、どの階層においても、元のテーブルでの出現順にリストされます。
|
148
148
|
|
149
149
|
```javascript
|
150
|
-
const
|
150
|
+
const addRowToTree = (treeArray, row) => {
|
151
151
|
let ary = treeArray;
|
152
152
|
for (let i=0; i < row.length; ++ i) {
|
153
153
|
if (i < row.length-1) {
|
@@ -165,7 +165,7 @@
|
|
165
165
|
return treeArray;
|
166
166
|
};
|
167
167
|
|
168
|
-
const treeArray = tableData.slice(1).reduce((ary, row) =>
|
168
|
+
const treeArray = tableData.slice(1).reduce((ary, row) => addRowToTree(ary, row), []);
|
169
169
|
|
170
170
|
console.log(JSON.stringify(treeArray, null, 2));
|
171
171
|
```
|
6
テキスト修正
answer
CHANGED
@@ -151,7 +151,7 @@
|
|
151
151
|
let ary = treeArray;
|
152
152
|
for (let i=0; i < row.length; ++ i) {
|
153
153
|
if (i < row.length-1) {
|
154
|
-
const key = `列${row[i][0]}`
|
154
|
+
const key = `列${row[i][0]}`;
|
155
155
|
let obj = ary.find(e => e[key] === row[i]);
|
156
156
|
if (!obj) {
|
157
157
|
obj = { [key]: row[i], list: [] };
|
5
テキスト修正
answer
CHANGED
@@ -140,4 +140,34 @@
|
|
140
140
|
|
141
141
|
- stackoverflow [Build tree array from flat array in javascript](https://stackoverflow.com/questions/18017869)
|
142
142
|
|
143
|
-
にいくつか出ています。ご質問にある表データの配列を加工して、上記に投稿されているいずれかの回答コードをベースにした階層化コードを作成する手もあるかもしれません。
|
143
|
+
にいくつか出ています。ご質問にある表データの配列を加工して、上記に投稿されているいずれかの回答コードをベースにした階層化コードを作成する手もあるかもしれません。
|
144
|
+
|
145
|
+
### 追記2
|
146
|
+
|
147
|
+
オブジェクトを経由しない別案を作成しました。こちらは、どの階層においても、元のテーブルでの出現順にリストされます。
|
148
|
+
|
149
|
+
```javascript
|
150
|
+
const addRow = (treeArray, row) => {
|
151
|
+
let ary = treeArray;
|
152
|
+
for (let i=0; i < row.length; ++ i) {
|
153
|
+
if (i < row.length-1) {
|
154
|
+
const key = `列${row[i][0]}`
|
155
|
+
let obj = ary.find(e => e[key] === row[i]);
|
156
|
+
if (!obj) {
|
157
|
+
obj = { [key]: row[i], list: [] };
|
158
|
+
ary.push(obj);
|
159
|
+
}
|
160
|
+
ary = obj.list;
|
161
|
+
} else {
|
162
|
+
ary.push(row[i]);
|
163
|
+
}
|
164
|
+
}
|
165
|
+
return treeArray;
|
166
|
+
};
|
167
|
+
|
168
|
+
const treeArray = tableData.slice(1).reduce((ary, row) => addRow(ary, row), []);
|
169
|
+
|
170
|
+
console.log(JSON.stringify(treeArray, null, 2));
|
171
|
+
```
|
172
|
+
|
173
|
+
- **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/oNbBaKE?editors=0012](https://codepen.io/jun68ykt/pen/oNbBaKE?editors=0012)
|
4
テキスト修正
answer
CHANGED
@@ -53,28 +53,15 @@
|
|
53
53
|
}
|
54
54
|
}
|
55
55
|
```
|
56
|
-
この`treeObj` から、目的の配列を得るための再帰関数 `treeObjToArray`
|
56
|
+
この`treeObj` から、目的の配列を得るための再帰関数 `treeObjToArray` を作成します。
|
57
57
|
|
58
58
|
```javascript
|
59
|
-
const keyCompare = (k1, k2) => {
|
60
|
-
const ch1 = k1[0], ch2 = k2[0];
|
61
|
-
const n1 = +k1.substring(2), n2 = +k2.substring(2);
|
62
|
-
return ch1 !== ch2 ? ch1.localeCompare(ch2) : n1 - n2;
|
63
|
-
}
|
64
|
-
|
65
|
-
```
|
66
|
-
上記の `keyCompare` は、セルの文字列を以下のように順序づけます。
|
67
|
-
|
68
|
-
`A-1` < `A-2` < `B-2` < `B-10` < `C-1`
|
69
|
-
|
70
|
-
`treeObj` から、目的の配列を得るための再帰関数 `treeObjToArray`は以下です。
|
71
|
-
```javascript
|
72
59
|
const treeObjToArray = obj => {
|
73
|
-
const entries = Object.entries(obj).sort(([k1], [k2]) =>
|
60
|
+
const entries = Object.entries(obj).sort(([k1], [k2]) => k1.substring(2) - k2.substring(2));
|
74
61
|
return entries.map(([k, v]) => ({
|
75
62
|
[`列${k[0]}`]: k,
|
76
63
|
list: Object.values(v)[0] ?
|
77
|
-
treeObjToArray(v) : Object.keys(v).sort((k1, k2) =>
|
64
|
+
treeObjToArray(v) : Object.keys(v).sort((k1, k2) => k1.substring(2) - k2.substring(2))
|
78
65
|
})
|
79
66
|
);
|
80
67
|
}
|
@@ -142,7 +129,7 @@
|
|
142
129
|
]
|
143
130
|
```
|
144
131
|
|
145
|
-
- **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/
|
132
|
+
- **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/KKVaGXj?editors=0012](https://codepen.io/jun68ykt/pen/KKVaGXj?editors=0012)
|
146
133
|
|
147
134
|
以上参考になれば幸いです。
|
148
135
|
|
3
テキスト修正
answer
CHANGED
@@ -19,7 +19,7 @@
|
|
19
19
|
上記の配列`tableData`から、階層構造を復元したオブジェクトを作ります。その際に lodash の [_.set](https://lodash.com/docs/#set)を使います。
|
20
20
|
|
21
21
|
```javascript
|
22
|
-
const treeObj = tableData.slice(1).reduce((
|
22
|
+
const treeObj = tableData.slice(1).reduce((obj, path) => _(obj).set(path, null).value(), {});
|
23
23
|
```
|
24
24
|
上記によって、`treeObj` に下記のようなオブジェクトが得られます。
|
25
25
|
|
2
テキスト修正
answer
CHANGED
@@ -1,31 +1,9 @@
|
|
1
1
|
こんにちは
|
2
2
|
|
3
|
-
いろいろなやり方がありそうですが、一例を挙げておきます。
|
4
|
-
|
5
|
-
|
3
|
+
いろいろなやり方がありそうですが、一例を回答します。以下の二次元配列 `tableData` から目的のJSONを得るコードを挙げます、
|
6
|
-
|
7
4
|
```javascript
|
8
|
-
const
|
5
|
+
const tableData = [
|
9
|
-
`列A 列B 列C
|
10
|
-
A-1 B-1 C-1
|
11
|
-
A-1 B-1 C-2
|
12
|
-
A-1 B-2 C-3
|
13
|
-
A-1 B-2 C-4
|
14
|
-
A-2 B-3 C-5
|
15
|
-
A-2 B-3 C-6
|
16
|
-
A-2 B-4 C-7
|
17
|
-
A-2 B-4 C-8
|
18
|
-
A-1 B-5 C-9
|
19
|
-
A-2 B-2 C-10`;
|
20
|
-
```
|
21
|
-
|
22
|
-
以下によって、各セルの値の配列を得ます。
|
23
|
-
```javascript
|
24
|
-
|
6
|
+
[ '列A', '列B', '列C' ],
|
25
|
-
```
|
26
|
-
上記によって、 `tableData` は、以下のような二次元配列になります。
|
27
|
-
```javascript
|
28
|
-
[
|
29
7
|
[ 'A-1', 'B-1', 'C-1' ],
|
30
8
|
[ 'A-1', 'B-1', 'C-2' ],
|
31
9
|
[ 'A-1', 'B-2', 'C-3' ],
|
@@ -36,12 +14,12 @@
|
|
36
14
|
[ 'A-2', 'B-4', 'C-8' ],
|
37
15
|
[ 'A-1', 'B-5', 'C-9' ],
|
38
16
|
[ 'A-2', 'B-2', 'C-10' ]
|
39
|
-
]
|
17
|
+
];
|
40
18
|
```
|
41
19
|
上記の配列`tableData`から、階層構造を復元したオブジェクトを作ります。その際に lodash の [_.set](https://lodash.com/docs/#set)を使います。
|
42
20
|
|
43
21
|
```javascript
|
44
|
-
const treeObj = tableData.reduce((o, path) => _(o).set(path, null).value(), {});
|
22
|
+
const treeObj = tableData.slice(1).reduce((o, path) => _(o).set(path, null).value(), {});
|
45
23
|
```
|
46
24
|
上記によって、`treeObj` に下記のようなオブジェクトが得られます。
|
47
25
|
|
@@ -164,7 +142,7 @@
|
|
164
142
|
]
|
165
143
|
```
|
166
144
|
|
167
|
-
- **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/
|
145
|
+
- **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/wvMgYMX?editors=0012](https://codepen.io/jun68ykt/pen/wvMgYMX?editors=0012)
|
168
146
|
|
169
147
|
以上参考になれば幸いです。
|
170
148
|
|
1
テキスト修正
answer
CHANGED
@@ -87,9 +87,8 @@
|
|
87
87
|
```
|
88
88
|
上記の `keyCompare` は、セルの文字列を以下のように順序づけます。
|
89
89
|
|
90
|
-
`A-1` < `A-2` < `B-
|
90
|
+
`A-1` < `A-2` < `B-2` < `B-10` < `C-1`
|
91
91
|
|
92
|
-
|
93
92
|
`treeObj` から、目的の配列を得るための再帰関数 `treeObjToArray`は以下です。
|
94
93
|
```javascript
|
95
94
|
const treeObjToArray = obj => {
|
@@ -167,4 +166,13 @@
|
|
167
166
|
|
168
167
|
- **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/JjGEBgx?editors=0012](https://codepen.io/jun68ykt/pen/JjGEBgx?editors=0012)
|
169
168
|
|
170
|
-
以上参考になれば幸いです。
|
169
|
+
以上参考になれば幸いです。
|
170
|
+
|
171
|
+
|
172
|
+
### 追記
|
173
|
+
|
174
|
+
別案を検討する際の参考情報です。一次元のオブジェクト配列から、オブジェクト間の階層構造を復元した配列に変換するコードの例は
|
175
|
+
|
176
|
+
- stackoverflow [Build tree array from flat array in javascript](https://stackoverflow.com/questions/18017869)
|
177
|
+
|
178
|
+
にいくつか出ています。ご質問にある表データの配列を加工して、上記に投稿されているいずれかの回答コードをベースにした階層化コードを作成する手もあるかもしれません。
|