0

Suppose I have two json objects and I need to merge them.

css: [{
        drag: "mode() == 'layout'",
        ui_draggable: "mode() == 'layout'"
}]

css: [{
        someclass : true
}]

I want to end up with:

css: [{
        drag: "mode() == 'layout'",
        ui_draggable: "mode() == 'layout'",
        someclass : true
}]

After some further trial I came up with this but I assume I have place a few bugs or useless lines of code in it.

I came up with this code after a little playing around. My needs didn't need to recurse more than two levels so this is just fine. It could be much refined I am sure but it works great for binding knockout. Here is an example of how I used it to extend jquery unobtrusive knockoutjs

    var settings = {
        text: 'SelectedCard().CardData.Title',
        visible: "mode() != 'edit' || !isMyCard()",
        css: [{ drag: "mode() == 'layout'" , selectedElement: "selectedCardElement() == '_titlePreview'"}]
    };
    var settings2 = 
        {
            css: [{ drag: "mode() == 'layout'"}]
    };
   var settings3 =  merge(settings, settings2);

function merge(first, second) {

    for (var a1 in first) {
        // if second object is null we are finished.
        used.push(a1);
        if (second[a1] == null) {
            continue;
        } else {

            var ob2 = second[a1];
            if (typeof (first[a1]) != typeof (ob2)) {
            throw new Error("conflicting properties named:" + a1);
            }

            if ($.isArray(first[a1])) {

                for (var i = 0; i < ob2.length; i++) {
                    first[a1].push(ob2[i]);
                }

            } else {
                // matching property. 
                return merge(first[a1], second[a1]);
            }
        }
    }
    for (var a2 in second) {
        if (used.indexOf(a2) < 0) {
            first[a2] = second[a2];
        }
    }
    return first;
}
3

1 Answer 1

3

1) To merge both objects with a one-way overwrite, this will do it:

for (var attrname in obj2) { 
    obj1[attrname] = obj2[attrname]; 
}

2) To merge selectively, both ways:

obj1.someclass = obj2.someclass;

-or-

obj2["someclass"] = obj1["someclass"];

In this case, if the property does not yet exist in the object it does not need to be defined before assigning it.

3) Consider using a library like Underscore.js for performing "array functions" similar to this:

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);

returns [1, 2, 3, 101, 10] 

4) Lastly, here's a strong resource for formatting JSON objects, arrays and a combination thereof: jsonexample.com. This will be helpful as you get into complex "array functions".

Cheers!

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

Comments

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.