通过键将对象添加到属性(prop的位置未知)Javascript

时间:2018-04-23 14:35:18

标签: javascript function object

我有一个像这样的对象:

defObj:

{
 id: 101,
 email: 'jack@dev.com',
 personalInfo: {
        name: 'Jack',
        addresses: {
            firstAddress : {
                  line1: 'westwish st',
                  line2: 'washmasher',
                  city: 'wallas',
                  state: 'WX'
            }
        }
    }
}

和这样的对象:

addObj:

secondAddress : {
 line1: "aStreet",
 city : "aCity",
 state : "aState"
}

我想要一个像这样的功能:

addObjectToProperty(defObj, propertyName, addObj);

基本上它将defObj作为参数(如第一个对象),在其中搜索属性(如地址)并将obj添加到它(基本上“喜欢”一个数组,但在我的情况下它不能是一个数组,它必须是一个对象。)

用法示例如下:

addObjectToProperty(defObj,"addresses",addObj);

结果将是这样的:

{
     id: 101,
     email: 'jack@dev.com',
     personalInfo: {
            name: 'Jack',
            addresses: {
                firstAddress : {
                      line1: 'westwish st',
                      line2: 'washmasher',
                      city: 'wallas',
                      state: 'WX'
                },secondAddress : {
                  line1: "aStreet",
                  city : "aCity",
                 state : "aState"
                 } 
            }
        }
    }

我将如何实现这样的功能?我无法改变对象的结构(比如在其中放置数组)并且我不允许使用像underscore.js这样的外部库 问候!

4 个答案:

答案 0 :(得分:0)

如果我正确理解您,您需要以递归方式在对象中搜索具有给定名称的属性,并将其他对象的内容复制到其中。这个功能可以做到:

function addObjectToProperty(toObj, underName, addObj) {
    for (let name in toObj) {
        if (name === underName) {
            Object.assign(toObj[name], addObj);
            return true;
        }
        if (typeof toObj[name] === 'object') {
            let added = addObjectToProperty(toObj[name], underName, addObj);
            if (added) return true;
        }
    }
}

用你的例子(我在评论中提到的修改)尝试了它,它产生了你要求的结果。

答案 1 :(得分:0)

您可以通过检查对象的键和值来使用迭代和递归方法。如果未找到则迭代嵌套对象。



function addObjectToProperty(object, key, value) {
    return Object.entries(object).some(([k, v]) =>
        k === key
            ? Object.assign(v, value)
            : v && typeof v === 'object' && addObjectToProperty(v, key, value)
    );
}

var defObj = { id: 101, email: 'jack@dev.com', personalInfo: { name: 'Jack', addresses: { firstAddress: { line1: 'westwish st', line2: 'washmasher', city: 'wallas', state: 'WX' } } } },
    addObj = { secondAddress: { ine1: "aStreet", city: "aCity", state: "aState" } };

addObjectToProperty(defObj, "addresses", addObj);

console.log(defObj);

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 2 :(得分:0)

您可以循环addObj或者如果只有一个属性

function addObjectToProperty(target, prop, source)
{
   var key = Object.keys(source)[0];
   target.personalInfo[prop][key] = source[key];
}
addObjectToProperty(defObj,"addresses",addObj);

但如果有多个这样的话,那么迭代source

的键
function addObjectToProperty(target, prop, source)
{
   Object.keys(source).forEach( s => (target.personalInfo[prop][s] = source[s]) );
}

答案 3 :(得分:0)

这样的对象语法
secondAddress : {
 line1: "aStreet",
 city : "aCity",
 state : "aState"
}

错了。

您需要一个递归来检查密钥并传递另一个参数来命名这个新密钥

var defObj = {
  id: 101,
  email: 'jack@dev.com',
  personalInfo: {
    name: 'Jack',
    addresses: {
      firstAddress: {
        line1: 'westwish st',
        line2: 'washmasher',
        city: 'wallas',
        state: 'WX'
      }
    }
  }
}
var secondAddress = {
  line1: "aStreet",
  city: "aCity",
  state: "aState"
}

function addObjectToProperty(originalObj, prop, newObj, addName) {
  //iterating object using for..in
  for (var keys in originalObj) {
    // checking if key name matches and if this is a object
    if (keys === prop && typeof originalObj[keys] === 'object') {
      // add new value
      originalObj[keys][addName] = newObj;
    } else if (typeof originalObj[keys] === 'object') {
     // else call the same function with  new value
     // here originalObj[keys] will change
      addObjectToProperty(originalObj[keys], prop, newObj, addName)
    }
  }
}
addObjectToProperty(defObj, 'addresses', secondAddress, 'secondAddress');
console.log(defObj)