6

Lets take a look at the example below:

var ref = {
    "fullName": {
        "rules": {
            "type": "string",
            "minLength": 4,
            "maxLength": 64
        },
        "description": "Full name of a user."
    }
};

var user = {
    "fullName": {
        "rules": {
            "required": true,
            "maxLength": 128
        },
        "message": "You have submitted a wrong full name."
    }
};

Now what I want is this:

  1. Merge objects & properties.
  2. Keep the properties of the second object IF they are set already (maxLength)

Below is the result that I expect:

var res = {
    "fullName": {
        "rules": {
            "required": true,
            "maxLength": 128
            "type": "string",
            "minLength": 4
        },
        "description": "Full name of a user.",
        "message": "You have submitted a wrong full name."
    }
};

What I have tried:

function mergeNestedObjects(firstObject, secondObject) {
    var finalObject = {};
    
    for (var propertyKey in firstObject) {
        var propertyValue = firstObject[propertyKey];
        
        if (typeof(propertyValue) === "object") {
            finalObject[propertyKey] = mergeNestedObjects(firstObject[propertyKey], secondObject[propertyKey]);
        } else if (secondObject[propertyKey] === undefined) {
            finalObject[propertyKey] = firstObject[propertyKey];
        } else {
            finalObject[propertyKey] = secondObject[propertyKey];
        }
    }
    
    return finalObject;
}

The function above merges but somehow doesnt nest the properties.

UPDATE & ANSWER got it working, I forgot too itterate through the second object, how dumb. Thanks to @AnthonyGrist

function mergeProperties(propertyKey, firstObject, secondObject) {
    var propertyValue = firstObject[propertyKey];

    if (typeof(propertyValue) === "object") {
        return mergeNestedObjects(firstObject[propertyKey], secondObject[propertyKey]);
    } else if (secondObject === undefined || secondObject[propertyKey] === undefined) {
        return firstObject[propertyKey];
    }
    
    return secondObject[propertyKey];
}

function mergeNestedObjects(firstObject, secondObject) {
    var finalObject = {};
    
    // Merge first object and its properties.
    for (var propertyKey in firstObject) {
        finalObject[propertyKey] = mergeProperties(propertyKey, firstObject, secondObject);
    }

    // Merge second object and its properties.
    for (var propertyKey in secondObject) {
        finalObject[propertyKey] = mergeProperties(propertyKey, secondObject, firstObject);
    }
    
    return finalObject;
} 
6
  • 2
    You're only ever iterating over the keys of firstObject, so your resulting object is only ever going to have the same keys as the first object passed in. You'll also need to iterate over the keys of secondObject, and add those which are missing. Commented Dec 13, 2012 at 13:59
  • 1
    @onlineracoon: I tried your code, and the properties nest correctly. The only issue is that some of the properties are missing, as Anthony pointed out. Commented Dec 13, 2012 at 14:01
  • @AnthonyGrist that worked, how stupid of me lol. Now however I got this: pastebin.com/Zma8kLY6 can it be made any shorter, it looks like im doing alot of duplicated code Commented Dec 13, 2012 at 14:02
  • @onlineracoon You may answer your own question and mark it as accepted. :) Commented Dec 13, 2012 at 14:05
  • I want @AnthonyGrist to answer it, since he gave the answer and he deserves the credits Commented Dec 13, 2012 at 14:05

2 Answers 2

6
function mergeProperties(propertyKey, firstObject, secondObject) {
    var propertyValue = firstObject[propertyKey];

    if (typeof(propertyValue) === "object") {
        return mergeNestedObjects(firstObject[propertyKey], secondObject[propertyKey]);
    } else if (secondObject[propertyKey] === undefined) {
        return firstObject[propertyKey];
    }

    return secondObject[propertyKey];
}

function mergeNestedObjects(firstObject, secondObject) {
    var finalObject = {};

    // Merge first object and its properties.
    for (var propertyKey in firstObject) {
        finalObject[propertyKey] = mergeProperties(propertyKey, firstObject, secondObject);
    }

    // Merge second object and its properties.
    for (var propertyKey in secondObject) {
        finalObject[propertyKey] = mergeProperties(propertyKey, secondObject, firstObject);
    }

    return finalObject;
} 
Sign up to request clarification or add additional context in comments.

1 Comment

There is a flaw in this. This fails when we merge a = {a: {z: 1}, b: {y:1}, c:{z:1}}; b = {c:{zye: 1}}; Because we are not checking if the key exist in the second object in the call: return mergeNestedObjects(firstObject[propertyKey], secondObject[propertyKey])
2

Pretty old question, but can be useful. A little bit of recursion.

function mergeObjects(og, so) {
    for (var key in so) {
        if (typeof (og[key]) === 'object') {
            mergeObjects(og[key], so[key]);
        } else {
            if (og[key] || typeof (og[key]) === 'boolean') {
                og[key] = so[key];
            }
        }
    }
    return og;
}

mergeObjects(ref, user);

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.