【问题标题】:Traversing object hierarchy based on provided keys?基于提供的键遍历对象层次结构?
【发布时间】:2019-04-30 17:07:24
【问题描述】:

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

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

部分字段 > 和 component 只是 Object 中的键。它们是路点,因此我们可以沿着层次结构向下移动。显然 section 是头部,我们的切入点。

element 是目标键,value 是要设置的值。

由于存在不同深度的元素,我想做以下事情:

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

这是一个浅层访问,在内部它会这样做:

dataObj[section][element] = value;

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


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

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

动态定义元素路径的最佳方法是什么,因此我们跳过作为“null”传入的键?

例如:

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

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

将在内部构造为:

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

您可能已经注意到,我们跳过了 [pair][component],因为这些插槽是作为 null(s) 传入的。

【问题讨论】:

  • 最好使用数组而不是定义的参数。数组上的简单循环

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


【解决方案1】:

与其拥有一长串特定参数,只需将一个对象传递给函数即可。这样你只传递你需要的东西,并且在调用时不会有任何“空”引用要处理。

使用这个实现,这个调用可以缩短成这样:

您当前的实现:

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

使用对象作为参数:

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

【讨论】:

  • 让我测试一下。我想我以前有过这样的设置。不完全是我的问题的答案,因为它需要更改实现,但它可能作为一种解决方案。我很乐意接受它并继续前进,因为它可能会使我的整个问题变得毫无意义。
【解决方案2】:

您可以使用rest parameters 来获取传递给数组的参数。然后使用reduceRight创建一个对象

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

【讨论】:

  • 我使用该对象作为遍历我的原始数据结构的手段?
  • @mbilyanov 对不起,我没听懂你
  • 因为这些关键字有点像地图,从某种意义上说是为了到达需要更改的键所要遵循的路点,我不确定我将如何使用reduce 遍历我的原始数据集的结果。所以我想,我将使用它来向下移动原始数据结构中每个键的reduce 结果中每个键的层次结构。
  • @mbilyanov 我已经更新了代码。不确定这是否是您需要的。
  • 您的解决方案很好地回答了这个问题。谢谢!但是有一个问题,除了最后两个 exportIdorange 之外,所有参数都是嵌套的。我正在尝试修复您的代码,以便我们真正沿着层次结构走,所以history', 'current', null, null, 'fruit', 'apple' 将是history: { current: { fruit: apple } }
猜你喜欢
  • 2011-09-23
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多