JavaScript:从对象数组中的对象数组中提取属性值作为数组

时间:2019-07-15 18:46:37

标签: javascript arrays javascript-objects

我有一个具有以下结构的JavaScript对象数组:

somedata = {
  foo: {
    bar: [
      {
        baz: [
          {
            someprop: 'a'
          },
          {
            someprop: 'b'
          },
          {
            someprop: 'c'
          }
        ]
      },
      {
        baz: [
          {
            someprop: 'd'
          },
          {
            someprop: 'e'
          },
          {
            someprop: 'f'
          }
        ]
      }
    ]
  }
}

我想从此JavaScript对象中提取someprop字段作为数组['a', 'b', 'c', 'd', 'e', 'f']

目前,这是我的代码逻辑,用于将someprop字段提取为数组:

const result = []
somedata.foo.bar.forEach(x => {
  x.baz.forEach(y => {
    result.push(y.someprop)
  })
})
console.log(result) // prints ["a", "b", "c", "d", "e", "f"]

我试图通过创建一个函数使代码更可重用:

function extractToArray(data, arr, prop) {
  let result = []
  data.forEach(x => {
    x[arr].forEach(y => {
      result.push(y[prop])
    })
  })
  return result;
}
console.log(extractToArray(somedata.foo.bar, 'baz', 'someprop'))

但是有没有更简洁,优雅,更简洁的方法来实现这一目标?


注意: possible duplicate涵盖了对象数组,但这是关于对象数组中的对象数组(因此,简单的map解决方案将不起作用)。

4 个答案:

答案 0 :(得分:2)

您可以创建递归函数,该函数将在任何级别上找到您的道具并返回数组。

const somedata = {"foo":{"bar":[{"baz":[{"someprop":"a"},{"someprop":"b"},{"someprop":"c"}]},{"baz":[{"someprop":"d"},{"someprop":"e"},{"someprop":"f"}]}]}}

function get(data, prop) {
  const result = [];
  for (let i in data) {
    if (i == prop) result.push(data[prop]);
    if (typeof data[i] == 'object') result.push(...get(data[i], prop))
  }
  return result;
}

console.log(get(somedata, 'someprop'))

答案 1 :(得分:2)

您可以使用flatMap

1

请注意,当前并非所有浏览器都支持此功能,因此您可能要使用polyfill。

答案 2 :(得分:1)

在一个函数表达式中执行的递归函数:

const extractToArray = (data, prop) => Object(data) !== data ? [] 
    : Object.values(data).flatMap(v => extractToArray(v, prop)) 
            .concat(prop in data ? data[prop] : []);

var somedata = {foo: {bar: [{baz: [{someprop: 'a'},{someprop: 'b'},{someprop: 'c'}]},{baz: [{someprop: 'd'},{someprop: 'e'},{someprop: 'f'}]}]}}
console.log(extractToArray(somedata, "someprop"));

从某种意义上说,当属性不总是存在或在数据结构中并不总是处于相同深度时,它也可以使用。

答案 3 :(得分:1)

对于其他有类似问题的人,我正在使用JSON.parse reviver parameter

添加一个更通用的(但可能效率更低)替代方案

var arr = [], obj = {foo:{bar:[{baz:[{someprop:"a"},{someprop:"b"},{someprop:"c"}]},{baz:[{someprop:"d"},{someprop:"e"},{someprop:"f"}]}]}}

JSON.parse(JSON.stringify(obj), (k, v) => k === 'someprop' && arr.push(v))

console.log(arr)