0

I have asked this question before, but it seems the solution doesn't work well.

I have two objects:

var a = [{ x: 0, y: 0, color: "green", value: undefined, weight: 1 }, { x: 0, y: 1, color:   "red", value: undefined, weight: 1 }];

var b = [{ x: 0, y: 0, value: 1}, { x: 0, y: 1, value: 3}];

I want to join them into a single object, like this:

var c = [{ x: 0, y: 0, color: "green", value: 1, weight: 1 }, { x: 0, y: 1, color: "red", value: 3, weight: 1 }];

Note: array A will always have 25 entries, while array b not.

The proposed solution was: var extendedArray = $.extend({}, a, b);

However this makes an array of two entries, where not all values are preserved.

I have also tried the following functions:

var e = $.merge(a, b);
var output = a.concat(b);

function jsonConcat(o1, o2) {
    for (var key in o2) {
        o1[key] = o2[key];
    }
    return o1;
}



var c = {};
c = jsonConcat(c, a);
c = jsonConcat(c, b);

Any help or push in the right direction would be very much appreciated!

5
  • What if b[0].weight == 2? Which would take precedence? Commented Aug 1, 2014 at 7:57
  • Not possible, the weight will always be 1 if x: 0 and y: 0 on both objects. Commented Aug 1, 2014 at 8:17
  • What is supposed to happen if a has n values and b has j values? How should they merge if n > j? How about if j > n? Commented Aug 1, 2014 at 9:32
  • b will never have more values than a , but it is likely that a has more values than b. The values of a should be kept, while it is important that the value fields from b are added to object a. I hope you still understand it, thanks for your help. Commented Aug 1, 2014 at 9:37
  • Got it. I updated my answer and tested it on the sample you provided on jsfiddle Commented Aug 1, 2014 at 9:45

3 Answers 3

1

Edited to reflect that b can be smaller but never larger than a.

function merge(a,b){
    //Don't want to mutate a
    var result = a.slice();
    for(var i = 0; i < b.length; i++){
        for (var attrname in b[i]) {
             result[i][attrname] = b[i][attrname]; 
         }
    }
    return result;
}

Code partly taken from accepted answer in: How can I merge properties of two JavaScript objects dynamically?

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your help and time. Tried to implement your function with the fiddle, but it seems to not overwrite values. If you check the fiddle (jsfiddle.net/RsB33/2) with your function, the last entry should be: color: "red", value: 1, weight: 5, x: 4, y: 4. But the value is still undefined, any idea why this is?
Unless I have misunderstood how you expect this to work, it should be undefined because b.length is 16 and a.length is 25 so it only merges into the first 16 of a. What do you expect to happen with 17-25?
1

Assuming that the two arrays have the same length, an in place merge could be something like this:

var a = [{ x: 0, y: 0, color: "green", value: undefined, weight: 1 }, { x: 0, y: 1, color:   "red", value: undefined, weight: 1 }];

var b = [{ x: 0, y: 0, value: 1, weight: 1 }, { x: 0, y: 1, value: 3, weight: 1 }];


function merge_objects(o1, o2) {
    Object.keys(o2).forEach(
        function(key) {
            o1[key] = o2[key];
        });
}

function merge(a, b) {
    if (a.length != b.length) {
        throw new Error();
    }
    for (var ix=0; ix<a.length; ix++) {
        merge_objects(a[ix], b[ix]);
    }
}

1 Comment

Sorry forgot to add. Array a will always have the same length, but array b not.
1

$.extend without the first argument set to true will only merge the "first level" of your objects. It works if your properties are only strings and numbers, but if some properties are objects, it can result in unexpected behaviour.

I think you're looking for $.extend(true,obj1,obj2) .

example

var a = [{ x: 0, y: 0, color: "green", value: undefined, weight: 1 }, { x: 0, y: 1, color:   "red", value: undefined, weight: 1 }];

var b = [{ x: 0, y: 0, value: 1, weight: 1 }, { x: 0, y: 1, value: 3, weight: 1 }];

var c = $.extend(true,[],a,b);
console.log(c instanceof Array); // true

see the doc for details

the first argument true tells the method to perform a "deep" copy, recursively.

2 Comments

$.extend returns an object not an array.
I have made an jsfiddle where I am trying to show the problem: jsfiddle.net/RsB33/1 as you can see in the console, not all values have been preserved and somehow object {x:4, y:4, ... } appears twice. Any idea why?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.