前提・実現したいこと
JavaScriptで配列の変換をしたい
該当のソースコード
最初の配列
javascript
1let data = [["a","b",10],["a","b",20],["a","c",30],["a","c",40],["a","d",50]];
結果
javascript
1[["a","b",30],["a","c",70],["a","d",50];
data[0]とdata[1]が一致した時に,data[2]を足した配列を返したいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
すでにベストアンサーが決まった後に失礼します。
考え方
この回答では、考え方として以下の1.〜 **4. **の考え方によるアプローチを採ります。
**1.**説明の便宜上、data
の要素である配列(例: ["a","b",10]
)について、
・末尾の要素を除いた配列(例: ["a", "b"]
)を、キー配列と呼ぶ。
・末尾の要素(例: 10
) のことを、単に 数値 と呼ぶ。
**2.**所与の data
から、まず以下の2点を作成
(ⅰ)totals
:各キー配列別の数値の合計が格納されたオブジェクト
(ⅱ)keys
: data
の要素に出現するキー配列を、出現順に、かつ、重複なく含む配列
**3.**上記2.(ⅰ)のオブジェクト totals
には、キー配列が例えば ["a", "b"]
である数値の合計(ご質問にあるサンプルだと 30)が totals.a.b
に格納されるようにする。
・従って、ご質問の例だと、 totals
は以下のようなオブジェクトになる。
javascript
1// totals の例 2{ a: { b: 30, c: 70, d: 50 } }
**4.**オブジェクト totals
と keys
から、結果として望ましい形式の配列 result
を得る。
コード例
以下は、上記の考え方によるコードです。配列やオブジェクトの操作で便利なライブラリ lodash を使用しています。
javascript
1 2const [totals, keys] = data.reduce(([obj, keys], ary) => { 3 const [k, v] = [_.initial(ary), _.last(ary)]; 4 if (_.has(obj, k)) { 5 _.set(obj, k, _.get(obj, k) + v); 6 } 7 else { 8 _.set(obj, k, v); 9 keys.push(k); 10 } 11 return [obj, keys]; 12}, [{}, []]); 13 14const result = keys.map(k => [...k, _.get(totals, k)]);
上記のコードで使っている lodash のメソッドは以下です。
totals
のキー配列に対する値の取得、設定および存在確認: _.get, _.set, _.has- 配列から最後の要素を取得: _.last
- 配列から最後の要素を除いた配列の取得: _.initial
以下は、上記のコードを動作確認するためのサンプルです。動作確認のため、data
に要素を追加しています。
- 動作確認用CodePen: https://codepen.io/jun68ykt/pen/LYVMyMP?editors=0012
以上、参考になれば幸いです。
投稿2020/03/27 18:03
編集2020/03/29 01:01総合スコア9058
0
new Map()と分割代入の練習で作ってみました。
js
1let data = [["a", "b", 10], ["a", "b", 20], ["a", "c", 30], ["a", "c", 40], ["a", "d", 50], ["a", "b", "c", 50], ["a", "b", "c", 50]]; 2//[["a","b",30],["a","c",70],["a","d",50]; 3 4const aggregate = new Map(); 5data.forEach(keys_value => { 6 const value_keys = Array.from(keys_value); 7 value_keys.unshift(value_keys.pop()); 8 const [value, ...keys] = [...value_keys]; 9 aggregate.set(JSON.stringify(keys), (aggregate.get(JSON.stringify(keys)) || 0) + value); 10}); 11 12const result = [...aggregate.entries()].map(v => [...JSON.parse(v[0]), v[1]]); //[ [ "a", "b", 30 ], [ "a", "c", 70 ], [ "a", "d", 50 ], [ "a", "b", "c", 100 ] ] 13console.log(result);
json
1 [ [ 'a', 'b', 30 ], 2 [ 'a', 'c', 70 ], 3 [ 'a', 'd', 50 ], 4 [ 'a', 'b', 'c', 100 ] ]
投稿2020/03/27 15:41
編集2020/03/28 02:04総合スコア2826
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
複雑なので綺麗に収まりませんね。
js
1const data = [ 2 ["a","b",10], 3 ["a","b",20], 4 ["a","c",30], 5 ["a","c",40], 6 ["a","d",50] 7]; 8const result = Object.entries( 9 data 10 .map(([k1, k2, num]) => [`${k1}.${k2}`, num]) 11 .reduce((o, [k, num]) => ({...o, [k]: (o[k] || 0) + num}), {}) 12).map(([key, num]) => [...key.split('.'), num]); 13 14console.log(JSON.stringify(result, null, 2));
JSON
1[ 2 [ 3 "a", 4 "b", 5 30 6 ], 7 [ 8 "a", 9 "c", 10 70 11 ], 12 [ 13 "a", 14 "d", 15 50 16 ] 17]
投稿2020/03/27 05:06
総合スコア21203
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/27 05:59
2020/03/27 06:03
0
javascript
1const data = [["a","b",10],["a","b",20],["a","c",30],["a","c",40],["a","d",50]]; 2const o = data.reduce((a,c)=> a[c[0]] ? (a[c[0]][c[1]] ? {...a, [c[0]]:{...a[c[0]],[c[1]]: a[c[0]][c[1]] + c[2]} }: {...a, [c[0]]:{...a[c[0]],[c[1]]:c[2]}}) : {...a, [c[0]]:{[c[1]]:c[2]} },{}); 3const p = Object.keys(o).reduce((a,c) => a.concat([Object.keys(o[c]).map(e=>[c,e,o[c][e]])]),[]); 4console.log(p);
group をつくって、展開すると考えました。
投稿2020/03/27 04:18
総合スコア12705
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
思ったよりグダグダになったので、最適解は他の回答者におまかせします
投稿2020/03/27 03:57
総合スコア116724
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/27 03:57
2020/03/27 03:58
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。