Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

I have 2 array objects in Angular JS that I wish to merge (overlap/combine) the matching ones.

For example, the Array 1 is like this:

[
    {"id":1,"name":"Adam"},
    {"id":2,"name":"Smith"},
    {"id":3,"name":"Eve"},
    {"id":4,"name":"Gary"},
]

Array 2 is like this:

[
    {"id":1,"name":"Adam", "checked":true},
    {"id":3,"name":"Eve", "checked":true},
]

I want the resulting array after merging to become this:

[
    {"id":1,"name":"Adam", "checked":true},
    {"id":2,"name":"Smith"},
    {"id":3,"name":"Eve", "checked":true},
    {"id":4,"name":"Gary"},
]

Is that possible? I have tried angular's array_merge and array_extend like this:

angular.merge([], $scope.array1, $scope.array2);
angular.extend([], $scope.array1, $scope.array2);

But the above method overlap the first 2 objects in array and doesn't merge them based on matching data. Is having a foreach loop the only solution for this?

Can someone guide me here please?

share|improve this question
    
Are/will you use underscore or lodash? – Tushar Sep 15 '15 at 6:26
    
no. not familar with that and wont be using it. – Neel Sep 15 '15 at 6:35
up vote 1 down vote accepted

Not sure if this find of merge is supported by AngularJS. I've made a snippet which does exactly the same:

function merge(array1, array2) {
    var ids = [];
    var merge_obj = [];

    array1.map(function(ele) {
        if (!(ids.indexOf(ele.id) > -1)) {
            ids.push(ele.id);
            merge_obj.push(ele);
        }
    });

    array2.map(function(ele) {
    	var index = ids.indexOf(ele.id);
        if (!( index > -1)) {
            ids.push(ele.id);
            merge_obj.push(ele);
        }else{
        	merge_obj[index] = ele;
        }
    });

    console.log(merge_obj);
}

var array1 = [{
    "id": 1,
    "name": "Adam"
}, {
    "id": 2,
    "name": "Smith"
}, {
    "id": 3,
    "name": "Eve"
}, {
    "id": 4,
    "name": "Gary"
}, ]

var array2 = [{
    "id": 1,
    "name": "Adam",
    "checked": true
}, {
    "id": 3,
    "name": "Eve",
    "checked": true
}, ];

merge(array1, array2);

share|improve this answer
    
Thats look very good @AnandSudhanaboina I can use in that in my Angular project and it seems like a good approach. Thank you so much for that. I will give that try now. :) – Neel Sep 15 '15 at 7:06
    
Hi @AnandSudhanaboina I tested it in my app and it works well. However, the only thing is it changes the order of the resulting merge_obj by placing the matching ones at the top and the rest at the bottom. Is it possible to keep the same order as array 1 was but with the merged data? jsfiddle.net/Alien_time/16pd3dd5 – Neel Sep 15 '15 at 7:33
    
Updated the answer. If this works do mark as answer. Thanks. – Anand Sudhanaboina Sep 15 '15 at 7:37
    
Thats perfect and it works exactly like I wanted. Thank you so much @AnandSudhanaboina – Neel Sep 15 '15 at 7:52

Genuinely, extend in Angular works with object instead of array. But we can do small trick in your case. Here is another solution.

// a1, a2 is your arrays
// This is to convert array to object with key is id and value is the array item itself
var a1_ = a1.reduce(function(obj, value) {
    obj[value.id] = value;
    return obj;
}, {});
var a2_ = a2.reduce(function(obj, value) {
    obj[value.id] = value;
    return obj;
}, {});
// Then use extend with those two converted objects
var result = angular.extend([], a1_, a2_).splice(1)

Notes:

  • For compatibility, reduce may not work.
  • The after array will replace the previous one. This is because of implementation of extend in Angular.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.