2016-02-27 74 views
0

我正在使用lodash合併2個對象。因爲要合併的第二個對象我不知道它可能包含一個點符號字符串對象。 (不知道是不是一個更好的詞嗎?)使用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'} 

這不是預期的結果 - 而且我甚至不知道這應該如何在一個對象中兩次使用keys.name.name。

+0

使用它與合併之前,您應該扁平化你的第二個對象鍵。 – Darshan

回答

0

您在這兩個示例中使用的第二個參數不相同。當你想在對象鍵中使用一個點時,你需要在你的案例中引用鍵名(person.name)。

因此,您的第一個示例中的對象具有一個鍵person,該鍵指向具有name鍵的對象。相比之下,第二個示例中的對象有一個名爲person.name的鍵,它有些不同。在第二個樣品上訪問person鍵將返回undefined

0

一個小幫手

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