【问题标题】:How to enumerate complex javascript object如何枚举复杂的javascript对象
【发布时间】:2018-03-06 07:22:46
【问题描述】:

如何枚举复杂的 javascript 对象以获取纯值的属性路径?

例如,如果对象是:

let complex = {
  person: {name: 'mat', age: 31},
  car: {
      model: 'Volsan',
      engine: 'large', 
      doors:[
        { side:'right front', color: 'blue' },
        { side:'left rear', color: 'red' }
      ]
   }
};

结果会是这样的:

complex.person.name
complex.person.age
complex.car.model
complex.car.engine
complex.car.doors[0].side
complex.car.doors[0].color
complex.car.doors[1].side
complex.car.doors[1].color

这样只有那些“结束图表”的值

例如。这将是来自lodash的反向_.at:https://lodash.com/docs/4.17.5#at

【问题讨论】:

  • @Ahmad 他不是在问如何访问元素,而是在问如何获取所有元素的路径数组。
  • @Rajesh 我想他想列出所有路径。
  • 使用递归函数枚举每个级别,如果它是一个数组或对象,它会递归到其中并将它们的属性或索引附加到结果中。
  • 添加到@Barmar 的评论,使用数组表示法。所以不要使用complex.person.name,而是使用complex['person']['name']。这更容易实现,并且不需要对数组和对象进行任何特殊处理

标签: javascript lodash


【解决方案1】:

此递归解决方案使用Array.map() 和Object.keys() 将键添加到基本路径。然后我们使用Array.concat() 和spread 将结果数组展平:

const complex = {
  person: {name: 'mat', age: 31},
  car: {
      model: 'Volsan',
      engine: 'large', 
      doors:[
        { side:'right front', color: 'blue' },
        { side:'left rear', color: 'red' }
      ]
   }
}

const addDot = (b, s) => `${b}${b && '.'}${s}`
const wrapBrackets = (b, s) => `${b}[${s}]`

const mapPaths = (obj, base = '') => {
  if(typeof obj !== 'object') {
    return base;
  }

  const formatter = Array.isArray(obj) ? wrapBrackets : addDot;

  return [].concat(...Object.keys(obj)
    .map((key) => mapPaths(obj[key], formatter(base, key))))
};

const result = mapPaths(complex)

console.log(result);

【讨论】:

  • 非常漂亮的解决方案!我为我的目的添加了 valueOf() : if(typeof (obj.valueOf()) !== 'object') { 例如。可能有新的 Number(1123) 作为值。
猜你喜欢
  • 2010-09-10
  • 1970-01-01
  • 2021-10-08
相关资源
最近更新 更多