chakuze
chakuze

Reputation: 69

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).

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. 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.

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 e.g. 1st attribute in 1st array with 3rd attribute in 2nd array.

Hope someone can help me out!

Upvotes: 0

Views: 3863

Answers (5)

Soudipta Dutta
Soudipta Dutta

Reputation: 2122

        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' } ]
   */

Upvotes: 0

Alaa
Alaa

Reputation: 7

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;
    }

Upvotes: 0

Microfed
Microfed

Reputation: 2890

You could use Array.prototype.map or Array.prototype.reduce for that. And remember about time complexity! In case the objects are uniq by the key (_id or box) and arrays have equal lengths:

// 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.

Upvotes: 0

Anthony Grist
Anthony Grist

Reputation: 38345

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. It's also not dependent on the order of the items in the two arrays being identical (i.e. box:123 can be in index 1 in array1, and _id:123 can be in index 3 in array2).

/*
    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");

Upvotes: 0

Rory McCrossan
Rory McCrossan

Reputation: 337560

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. 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

Upvotes: 1

Related Questions