【问题标题】:Javascript merge object with nested properties带有嵌套属性的 Javascript 合并对象
【发布时间】:2012-12-01 10:18:19
【问题描述】:

让我们看看下面的例子:

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

现在我想要的是:

  1. 合并对象和属性。
  2. 如果已经设置了第二个对象的属性,则保留它们 (maxLength)

以下是我期望的结果:

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

我尝试过的:

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

上面的函数合并了,但不知何故没有嵌套属性。

UPDATE & ANSWER 搞定了,我忘了遍历第二个对象,太笨了。感谢@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;
} 

【问题讨论】:

  • 您只需要遍历 firstObject 的键,因此您生成的对象只会与传入的第一个对象具有相同的键。您还需要遍历secondObject 的键,并添加缺少的键。
  • @onlineracoon:我试过你的代码,并且属性嵌套正确。正如安东尼指出的那样,唯一的问题是缺少一些属性。
  • @AnthonyGrist 成功了,我真傻,哈哈。但是现在我得到了这个:pastebin.com/Zma8kLY6 可以让它更短吗,看起来我做了很多重复的代码
  • @onlineracoon 您可以回答自己的问题并将其标记为已接受。 :)
  • 我希望 @AnthonyGrist 回答它,因为他给出了答案并且他应得的学分

标签: javascript object merge


【解决方案1】:

相当老的问题,但可能很有用。 一点点递归。

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

【讨论】:

    【解决方案2】:
    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;
    } 
    

    【讨论】:

    • 这里有一个缺陷。当我们合并 a = {a: {z: 1}, b: {y:1}, c:{z:1}}; 时失败。 b = {c:{zye: 1}};因为我们没有检查调用中的第二个对象中是否存在键:return mergeNestedObjects(firstObject[propertyKey], secondObject[propertyKey])
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 2021-03-08
    • 2013-11-07
    • 2022-10-01
    • 1970-01-01
    • 2023-02-07
    • 2021-09-27
    相关资源
    最近更新 更多