“展平”一个对象数组?

时间:2017-11-10 13:47:32

标签: javascript arrays json lodash

使用纯JS或Lodash“压扁”JSON对象数组的最佳方法是什么?

例如我有一个数组

[
  {
  "name": "Mat",
  "age": "18",
  "studies": [
      {
        "subject": "English",
         "mark": 5
      },
      {
        "subject": "Maths",
         "mark": 4
      }
    ],
  },
  {
  "name": "Alice",
  "age": 20,
  "city": "New York"
  }
]

我希望得到像

这样的东西
[
  {
   "name": "Mat",
   "age": "18",
   "subject": "English",
   "mark": 5
  },
  {
   "name": "Mat",
   "age": "18",
   "subject": "Maths",
   "mark": 4
  },
  {
   "name": "Alice",
   "age": 20,
   "city": "New York"
  }
]

编辑:工作代码类似于

rows.forEach(row => {
    let newRow = {}

    _.forOwn(row, (value, key) => {
            value.forEach(item => {
              _.forOwn(item, (value, key) => {
                 newRow[key] = value
               })
            })

           } else {
             newRow[key] = value
           }
      })
  })

它不提供像name这样的第一级属性,现在它已经足够我的理由了,但现在我需要获取除了studies之类的字段之外的所有属性。

1 个答案:

答案 0 :(得分:2)

现代语法可以让你这样做:



var d = [{"name":"Mat","age":"18","studies":[{"subject":"English","mark":5},{"subject":"Maths","mark":4}]},{"name":"Alice","age":20,"city":"New York"}];

var r = d.reduce((a, {studies, ...rest}) =>
  [...a, ...(studies || [{}]).map(s => ({...s, ...rest}))]
, []); 

console.log(r);




浏览器支持有限,因此如果需要,请使用转发器。

这在.reduce()回调的第二个参数中使用新的 rest语法作为对象文字。所以基本上,studies数组被放入它自己的变量中,而rest将是一个包含所有剩余属性的对象。

然后我们使用扩展语法来表示数组文字,以便将当前累加器数组的成员以及新对象从studies映射到回调结果中。

.map()回调中,我们使用对象文字传播语法rest回调中分配.reduce()对象的属性,以及当前"研究的特性"对象返回一个新的对象文字。

如果没有studies,我们将空数组替换为空对象,以便它至少获得rest属性。

如果要变平的键是动态的,你仍然可以这样做,虽然它要长一点。



var d = [{"name":"Mat","age":"18","studies":[{"subject":"English","mark":5},{"subject":"Maths","mark":4}]},{"name":"Alice","age":20,"city":"New York"}];

function flatten(key, data) {
  return data.reduce((a, user) => {
    const arr = user[key];
    delete user[key];
    return [...a, ...(arr || [{}]).map(s => ({...s, ...user}))]
  }, []);
}

console.log(flatten("studies", d));




如果解构语法允许像{[key], ...user}这样的方括号表达式评估,那么它会清理它,但是现在它们不会