3
4

More than 1 year has passed since last update.

js 連想配列(オブジェクト)で同じキーの要素をまとめる 配列を持つプロパティ 

Posted at

以下のような連想配列(オブジェクト)があるとする。

input.js
var array = [
  {key1:'aa', key2:'b',  code:'c'},
  {key1:'a',  key2:'b',  code:'d'},
  {key1:'aa', key2:'bb', code:'e'},
  {key1:'a',  key2:'bb', code:'f'},
  {key1:'aa', key2:'bb', code:'g'},
]

やりたいこと

これを、key1が同じものでまとめて、さらに、key2が同じものでまとめる。
連想配列の下に、連想配列を持ち、codeが同じなら配列にする。
結果的に以下のような形にしたい。

result.js
array = {
  aa:{
     b:['c'],
     bb:['e','g']
  },
  a:{
     b:['d'],
     bb:['f']
  }
}



試行錯誤した結果、以下のようなコードになったが、
できれば、mapやreduce,filterなど使って、もう少しスマートに書きたかった。

app.js
var newArr = {};
array.forEach(function(data) {
  var key1 = data['key1'];
  var key2 = data['key2'];
  var code = data['code'];
  var obj = {};

  if(newArr[key1] == undefined) {
     newArr[key1] = obj; // ---- ①
     // 未定義ならそのままcodeを入れる
     if(newArr[key1][key2] == undefined) {
        newArr[key1][key2]=[code];
        console.log(key1+key2+code+'-----1');
     }else{
     // key2の中身は配列なので、そのままpushする
       newArr[key1][key2].push(code); // ------ ②
       console.log(key1+key2+code+'-----2');
     }
  }else{  
     if(newArr[key1][key2]==undefined){
       newArr[key1][key2]=[code];
       console.log(key1+key2+code+'-----3');
     }else{
       newArr[key1][key2].push(code);
       console.log(key1+key2+code+'-----4');
     }  
  }  
});

console.log(newArr);
array = newArr;

コンソールに表示される順番として、1,1,3,3,4となる。

悩んだところ

①参照
いきなり、newArr[key1][key2]; のように書くと、下のようなエラーが出るので、①のようにした。

Uncaught TypeError: Cannot read property 'b' of undefined 

if文のundefindのところを、''やnullとしていて、うまくいかなかった。

②参照
key1の中身が連想配列なので、key2の中に値を追加するときに、ずっと

  obj = {[key2]:code};
  Object.keys(newArr[key1][key2]).push(obj);
  obj = {[key2]:code};
  newArr = Object.assign(newArr[key1],obj);

のようなことをしていたので、うまくいかなかった。


参考

https://qiita.com/hirakuma/items/0c4fd425f76bccab858c

3
4
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4