简体   繁体   English

在两个JSON数组的条件下合并两个JSON对象

[英]Merging two JSON Objects under condition for two JSON Arrays

I have a problem merging two JSON objects, each from another array, into a new JSON object, in a new Array (the merging has to happen under given conditions). 我在将两个来自另一个数组的JSON对象合并到新Array中的新JSON对象时遇到了问题( 合并必须在给定条件下进行)。

Example: 例:

First Array: 第一个数组:

var array1 = [{box:123,name:xxx,amount:xxx},{box:321,....},...]
var array2 = [{_id:123,look:xxx,title:myBox1},{_id:321,.....},...]
var newArray = [{box:123,name:xxx,amount:xxx,look:xxx,title:myBox1},...]

What I basically need: Iterate over Array1, iterate over Array2. 我基本需要的是:遍历Array1,遍历Array2。 If box (array1) == _id (array2) merge all attributes from both objects into a new JSON and put it in the first free slot in a new array3. 如果box (array1) == _id (array2)将两个对象的所有属性合并到新的JSON中,然后将其放在新array3的第一个空闲插槽中。

I hope the example helps to see what I'm trying to do. 我希望该示例有助于了解我正在尝试做什么。 What is the best solution? 最好的解决方案是什么?

Normally the first attribute in both arrays are also the ones that need to be compared, but it would be could, if the solution would work also if I want to compare eg 1st attribute in 1st array with 3rd attribute in 2nd array. 通常,两个数组中的第一个属性也是需要比较的属性,但是如果我想将第一个数组中的第一个属性与第二个数组中的第三个属性进行比较,如果解决方案也能解决的话,那就可以。

Hope someone can help me out! 希望有人可以帮助我!

You can achieve this with two loops. 您可以通过两个循环来实现。 The first to iterate through the object stored in array1 and the second to iterate over the properties of the matching object in array2 . 第一个迭代访问array1存储的对象,第二个迭代访问array2匹配对象的属性。 Try this: 尝试这个:

var newArray = [];
for (var i = 0; i < array1.length; i++) {
    var obj = array1[i];
    if (array2[i] && obj.box == array2[i]._id) {
        for (key in array2[i]) {
            obj[key] = array2[i][key];
        }
        newArray.push(obj);
    }
};

Example fiddle 小提琴的例子

You can try this: 您可以尝试以下方法:

 array3=[]
for(item1 in array1){
          for(item2 in array2){
         if(item1.box == item2._id)
           array3.push(Merge_objects(item1,item2))
         }
      }



    function Merge_objects(obj1,obj2){
        var obj3 = {};
        for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
        for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
        return obj3;
    }

The following function would do it. 下面的函数可以做到这一点。 It's slightly longer than the other answers, but more generic (you can specify which of the properties are the ids, rather than sticking with box and _id ) and doesn't modify the original arrays in any way. 它比其他答案稍长,但是更通用(您可以指定哪个属性为id,而不是坚持使用box_id ),并且不会以任何方式修改原始数组。 It's also not dependent on the order of the items in the two arrays being identical (ie box:123 can be in index 1 in array1, and _id:123 can be in index 3 in array2). 这也不取决于两个数组中项目的顺序相同(即box:123可以在array1的索引1中, _id:123可以在array2的索引3中)。

/*
    a1 = the first array of objects
    id1 = the name of the property of each object in a1 that is its id
    a2 = the second array of objects
    id2 = the name of the property of each object in a2 that is its id
*/
function combine(a1, id1, a2, id2) {
    // create our new array to return
    var newArray = []
    // iterate over a1 (the outer loop)
    for(var i = 0, l = a1.length; i < l; i++) {
        var outer = a1[i]; // get the current object for this iteration
        // iterate over a2 (the inner loop)
        for(var j = 0, m = a2.length; j < m; j++) {
            var inner = a2[j]; // get the current object for this iteration of the inner loop
            if(outer[id1] == inner[id2]) { // compare the ids for the outer and inner objects
                var o = {}; // create a new blank object to add to newArray
                o[id1] = outer[id1]; // set its id (using the same property name as that of a1)
                for(var prop in outer) { // iterate over properties
                    if(prop != id1) { // ignore the id property, but copy the others
                        o[prop] = outer[prop]
                    }
                }

                for(var prop in inner) {
                    if(prop != id2) {
                        o[prop] = inner[prop]
                    }
                }

                // add this object to newArray
                newArray.push(o);
            }
        }
    }

    // return newArray
    return newArray;
}

Usage: 用法:

var array1 = [{box:123,name:'Name 1',amount:1},{box:321,name:'Name 2',amount:2}]
var array2 = [{_id:123,look:'Look 1',title:'My box 1'},{_id:321,look:'Look 2',title:'My box 2'}]
var newArray = combine(array1, "box", array2, "_id");

You could use Array.prototype.map or Array.prototype.reduce for that. 您可以为此使用Array.prototype.mapArray.prototype.reduce And remember about time complexity ! 并记住时间的复杂性 In case the objects are uniq by the key ( _id or box ) and arrays have equal lengths: 如果对象通过键( _idbox )是唯一的,并且数组的长度相等:

// TODO: implement your own comparator based on _id/box type
var first = array1.sort((a, b) => a._id - b._id);
var second = array2.sort((a, b) => a.box - b.box);
var merged = sorted_first.map((item, index) => Object.assign(item, second[index]));

You can easily adjust this to the different lengths case an so on, but you really need to know your data first. 您可以轻松地将其调整为不同的长度,以此类推,但是您确实确实需要首先了解您的数据。

        Creating the dummy datas, this is what the programming should be:
        var a = [{
            id: 1,
            name: 'name1',
          }, {
            id: 2,
            name: 'name2',
          }, {
            id: 3,
            name: 'name3',

          }];

          var b = [{
            id: 1,
            look: 'look1'
          }, {
            id: 321,
            look: 'look321'
          }, {
            id: 3,
            look: 'look3',

          }

          ];

        // put the object id : 321 and look : look321 into array a from array b
          for (var i = 0; i < b.length; i++) {
            var obj_b= b[i];
            var id_b= b[i].id;
            var idNotFound = true;
            a.forEach(function(rowOfA){
            var id_a = rowOfA.id;
            if(id_a == id_b ){
                idNotFound = false;
            }
            });
            if( idNotFound ){

                a.push( b[i] );
            }//if

        }
        // merge the objects with same ids into array a
            for (var i = 0; i < a.length; i++) {
                var id_a = a[i].id;
                var found = false;
                for (var j = 0; j < b.length; j++) {
                    var id_b= b[j].id;
                    if(id_a == id_b){
                      found = b[j];
                    }//if

                }//for2
                if (found) {
                    a[i]["look"] = found.look;
                }//if
            }//for1

            console.log('aa=>',a);
    /*
The output is  aa=> [ { id: 1, name: 'name1', look: 'look1' },
      { id: 2, name: 'name2' },
      { id: 3, name: 'name3', look: 'look3' },
      { id: 321, look: 'look321' } ]
   */

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM