使用 lodash 合并 2 个对象,但使用点表示法

Use lodash to merge 2 objects but with dot notation

本文关键字:表示 合并 lodash 对象 使用      更新时间:2023-09-26

我正在使用 lodash 合并 2 个对象。因为第二个要合并的对象我不知道它是否可能包含一个点表示法字符串对象。(不知道更好的词吗?

简单(工作)示例:

_.merge({person:{name: 'Marc', age: 28}}, {person:{name: 'Timo'}});
// This will return {person:{name: 'Timo', age: 28}}

但是现在使用点表示法:

_.merge({person:{name: 'Marc', age: 28}}, {'person.name': 'Timo'});
// This will return {person:{name: 'Marc', age: 28}, person.name: 'Timo'}

这不是预期的结果 - 我什至不知道这应该如何与一个对象中的键 person.name 两次一起工作。

您在两个示例中使用的第二个参数并不相同。当您想在对象键中使用点时,您需要在大小写中引用键名(person.name)。

因此,第一个示例中的对象具有一个键person,该键指向具有name键的对象。相比之下,第二个示例中的对象具有一个名为 person.name 的键,该键是不同的。访问第二个样本上的person键将返回undefined

一个小帮手

function setPath(obj, path, value){
    if(typeof path === "object"){
        //you might want to change this part to lodash
        return Object.keys(path)
            //sort ASC by key-length
            //to make sure that the key `person` would be processed 
            //before processing `person.name`
            .sort((a,b)=>a.length-b.length)
            //apply keys
            .reduce((o, k) => setPath(o, k, path[k]), obj);
    }
    var parts = String(path).split(".");
    for(var i = 0, last = parts.length-1, ctx = obj; i<last; ++i, ctx = v){
        var k = parts[i], v = ctx[k];
        if(v !== Object(v)){
            //you might want to throw an error, or to ignore these cases
            //it's up to you
            if(v != null) console.error("overwriting non null property at path: " + parts.slice(0, i+1).join("."));
      //simple
            v = ctx[k] = {};
            /*
            //check the next key, if it is an uint, 
            //then this should probably be an Array
            var w = parts[i+1];
            //check wether w contains an uint32 
            v = ctx[k] = (+w === (w>>>0))? []: {};
            */
        }
    }
    ctx[parts[last]] = value;
    return obj;
}

和用法

var a = { person: { name: "Marc", age: 28 } };
var b = { "person.name": "Timo" };
JSON.stringify(setPath(a, b), null, 2);