根据提供的键遍历对象层次结构?

时间:2019-04-30 17:07:25

标签: javascript node.js object data-structures data-modeling

我有一个接受以下参数的函数:

last_four

部分 字段 >和 component 只是对象中的键。它们是路标,因此我们可以沿层次结构行进。显然, 部分 是头,我们的切入点。

元素 是目标键, 是将要设置的值。

既然有不同深度的元素,我想做以下事情:

set(section, field, pair, component, element, value)

这是用于浅层访问的,在内部它会这样做:

set('utility', null, null, null, 'exportId', 'banana')

在其他情况下,当元素在对象内部更深时,可能需要执行以下操作:

dataObj[section][element] = value;

**/ As in
 * data: {
      utility: {
         exportId: 'banana'
      }
 *  }
 */


动态定义元素路径的最佳方法是什么,因此我们跳过以'null'形式传递的键?

例如:

dataObj[section][field][pair][component][element] = value;

内部构造为:

set('history', 'current', null, null, 'fruit', 'apple')

**/ As in
 * data: {
      history: {
         current: {
           fruit: 'apple'
        }
      }
 *  }
 */

您可能已经注意到,我们跳过了dataObj[section][field][element] = value; ,因为这些广告位是作为[pair][component]传递的。

2 个答案:

答案 0 :(得分:1)

只需将一个对象传递给函数即可,而不是包含一长串的特定参数。这样,您只需传递所需的内容,就不会在呼叫中处理任何“空”引用。

使用此实现,此调用可以简化为以下形式:

您当前的实施方式:

 set('utility', 'current', null, null, 'exportId', 'banana')

使用对象作为参数:

set({
   section:'utility', 
   field:'current', 
   element: 'exportId', 
   value:'banana'
});

答案 1 :(得分:0)

您可以使用yii2 docu来获取传递给数组的参数。然后使用rest parameters

创建一个对象

function set(...paths) { 
  return paths.reduceRight((r, key, i) => key !== null ? { [key] : r } : r)  
}

console.log(set('history', 'current', null, null, 'fruit', 'apple'))
console.log(set('utility', null, null, null, 'exportId', 'banana'))


以上功能将基于路径构造一个嵌套对象。如果您只想更新现有对象,则可以遍历该对象并设置如下值:

function set(dataObj, ...paths) {
  let value = paths.pop(),
      nested = dataObj;

  for (let i = 0; i < paths.length; i++) {
    const path = paths[i];

    if (i === paths.length - 1 && nested)
      nested[path] = value; // set the value if it's the final item

    if (path !== null && nested)
      nested = nested[path]; // get another level of nesting
  }

  return dataObj;
}

let obj = { utility: { exportId: 'banana' } }

console.log(set(obj, 'utility', null, null, null, 'exportId', 'orange'))

obj = {
  history: {
    current: {
      fruit: 'apple'
    }
  }
}

console.log(set(obj, 'history', 'current', null, null, 'fruit', 'orange'))