web-dev-qa-db-ja.com

キー、JavaScriptでJSON配列を組み合わせる

2つのRESTサービスで提供される2つのjson配列を組み合わせる必要があります。同じ「id」を持つエントリは一緒に属します。

json1 = [{id:1,name:'aaa'},
     {id:5,name:'ccc'},
     {id:3,name:'bbb'}
   ];

 json2 = [{id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
     {id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
     {id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
    ];

私は次の方法でjavascriptの結合/コピー/クローン化されたjson配列が必要です(angular2の私のモデル):

json3 = [{id:3,name:'bbb',parameter1:'x', parameter2:'y',   parameter3:'z'},
     {id:1,name:'aaa', parameter1:'u', parameter2:'v', parameter3:'w'},
     {id:5,name:'ccc', parameter1:'q', parameter2:'w', parameter3:'e'}
    ];

それらを組み合わせる方法はありますか?パラメーター名は正確に定義されておらず、可変パラメーターベクトルを使用する必要があります。

ループごとに混合して試してみました。とてもいようです。

13
user2083142

2つだけでなく、任意の数の配列を取り込むことができるように記述したい場合は、 arguments を利用して、次のようなことを行うことができます。

var json1 = [{id:1,name:'aaa'},{id:5,name:'ccc'},{id:3,name:'bbb'}];

var json2 = [{id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
 {id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
 {id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
];

function joinObjects() {
  var idMap = {};
  // Iterate over arguments
  for(var i = 0; i < arguments.length; i++) { 
    // Iterate over individual argument arrays (aka json1, json2)
    for(var j = 0; j < arguments[i].length; j++) {
       var currentID = arguments[i][j]['id'];
       if(!idMap[currentID]) {
          idMap[currentID] = {};
        }
       // Iterate over properties of objects in arrays (aka id, name, etc.)
      for(key in arguments[i][j]) {
          idMap[currentID][key] = arguments[i][j][key];
      }
    }
  }

  // Push properties of idMap into an array
  var newArray = [];
  for(property in idMap) {
    newArray.Push(idMap[property]);
  }
  return newArray;
}

var json3 = joinObjects(json1, json2);

これは動作するコードペンです。

4
Jacob Petersen

2つのワンライナー:

ダッシュ付き:

res = _(json1).concat(json2).groupBy('id').map(_.spread(_.assign)).value();

eS2015で:

res = json2.map(x => Object.assign(x, json1.find(y => y.id == x.id)));
38
georg

ES2015 georgの答えは素晴らしい作品です。

    json1 = [
    {id:1, test: 0},
    {id:2, test: 0},
    {id:3, test: 0},
    {id:4, test: 0},
    {id:5, test: 0}
];

json2 = [
    {id:1, test: 1},
    {id:3, test: 1},
    {id:5, test: 1}
];

json1.map(x => Object.assign(x, json2.find(y => y.id == x.id)));

結果:

{id:1, test: 1},
{id:2, test: 0},
{id:3, test: 1},
{id:4, test: 0},
{id:5, test: 1}
8
Killian Charlez

ネストされたループを使用して、対応する要素を見つけてマージします。

for (var i = 0; i < json1.length; i++) {
    var id = json1[i].id;
    for (var j = 0; j < json2.length; j++) {
        if (json2[j].id = id) {
            for (var key in json2[j]) {
                json1[i][key] = json2[j][key];
            }
            break;
        }
    }
}

最後に、json1には結合された要素が含まれます。

上記のコードは、json2のすべての要素がjson1の何かと一致することを前提としています。 json2に余分な要素がある場合、それらをjson1にコピーするには追加のループが必要になります。

1
Barmar

これは、id(スパース配列)をキーとするインデックスを最初に構築して、一致するid値を持つオブジェクトを検出および結合する方法です、最後に連結されて通常の配列に戻ります。

json3 = json1.concat(json2).reduce(function(index, obj) {
    if (!index[obj.id]) {
        index[obj.id] = obj;
    } else {
        for (prop in obj) {
            index[obj.id][prop] = obj[prop];
        }
    }
    return index;
}, []).filter(function(res, obj) {
    return obj;
});
json1 = [
    {id:1,name:'aaa'},
    {id:5,name:'ccc'},
    {id:3,name:'bbb'}
];

json2 = [
    {id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
    {id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
    {id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
];

json3 = json1.concat(json2).reduce(function(index, obj) {
    if (!index[obj.id]) {
        index[obj.id] = obj;
    } else {
        for (prop in obj) {
            index[obj.id][prop] = obj[prop];
        }
    }
    return index;
}, []).filter(function(res, obj) {
    return obj;
});

document.write('<pre>', JSON.stringify(json3, null, 4), '</pre>');

ブラウザが Object.assign をサポートしている場合:

json3 = json1.concat(json2).reduce(function(index, obj) {
    index[obj.id] = Object.assign({}, obj, index[obj.id]);
    return index;
}, []).filter(function(res, obj) {
    return obj;
});
1
trincot

forEachおよびfilterを使用して、要件を解決できます。

vehicleArray1 = [{id:1, name: "a"},{id:2, name: "b"},{id:3, name:"c"}];
vehicleArray2 = [{id:1, type: "two wheeler"},{id:2, type: "four wheeler"},{id:3, type:"six wheeler"}];
var outArr = [];
vehicleArray1.forEach(function(value) {
    var existing = vehicleArray2.filter(function(v, i) {
        return (v.id == value.id);
    });
    if (existing.length) {
        value.type = existing[0].type;
        outArr.Push(value)
    } else {
        value.type = '';
        outArr.Push(value);
    }
});
console.log(outArr)
1
KARTHIKEYAN.A
let json1 = [
    {id:1,name:'aaa'},
    {id:5,name:'ccc'},
    {id:3,name:'bbb'}
];

let json2 = [
    {id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
    {id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
    {id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
];

let result = json1.map(obj => {
    let data = json2.find(item => item.id === obj.id);
    return {...obj, ...data}
});
0
PrisonPants

これはあなたのためにそれを行う必要があります。コードがそれ自体で意味をなすことを願っています。この例では、常にjson1上の値json2値が両方存在する場合。それを変更したい場合は、オブジェクト参照を切り替える必要があります(src[i]およびobj[j])最も内側のループ。

// Will take src, and merge in the contents of obj.
// Expects an array of objects for both.
// Will keep src values in favour of obj values.
function extend(src, obj) {
  
  // Loop the src, in this case json1
  for (var i = 0; i < src.length; i++) {
    
    // For every loop of json1, also loop json2
    for (var j = 0; j < obj.length; j++) {
      
      // If we have matching IDs operate on this pair
      if (src[i].id == obj[j].id) {
          
        // For every key in the object being merged in,
        // if the key exists in src, ignore new value.
        // if the doesn't exist in src, take the new value.
        for (var key in obj[j]) {
          src[i][key] = src[i].hasOwnProperty(key) ? src[i][key] : obj[j][key];
        }
        
        // We found our matching pair, so break out of the json2 loop
        break;
        
      }
      
    }
    
  }
  
  return src;
}

// -------------------------------------------

var json1 = [{
  id: 1,
  name: 'aaa'
},{
  id: 5,
  name: 'ccc'
},{
  id: 3,
  name: 'bbb'
}];

var json2 = [{
  id: 3,
  parameter1: 'x', 
  parameter2: 'y', 
  parameter3: 'z'
},{
  id: 1,
  parameter1: 'u', 
  parameter2: 'v', 
  parameter3: 'w'
},{
  id: 5,
  parameter1: 'q', 
  parameter2: 'w', 
  parameter3: 'e'
}];

var json3 = extend(json1, json2);

// ---------------------------------------------

var pre = document.getElementById('out');
pre.innerHTML = JSON.stringify(json3);
<pre id="out"></pre>
0
Luke