扁平化嵌套对象数组

3

我有如下数据:

data = [
  {
    "foo": {"name":"foo-name"},
    "bar": {"name":"bar-name"}
  },
  {
    "baz": {"name":"baz-name"}
  }
]

我的期望输出是:

[
  { "foo": {"name":"foo-name"}},
  { "bar": {"name":"bar-name"}},
  { "baz": {"name":"baz-name"}}
]

我该怎么得到这个结构?我试过使用concat,但是意识到它不适用于嵌套对象而不是嵌套数组。然后我尝试了不同的迭代方法,但是没有达到我想要的效果。其中一种尝试如下:

const newData = data.map((x) => {
  return Object.keys(x).map(el => {
    return {[el]: x};
  })
})

但这只会使它更加嵌套。

3个回答

4
你可以使用 flatMap

let data = [{"foo": {"name":"foo-name"},"bar": {"name":"bar-name"}},{"baz": {"name":"baz-name"}}]

let final = data.flatMap(a => Object.entries(a).map(([k, v]) => ({
  [k]: v
})))

console.log(final)


3

一个选项是将数据reduce成一个数组,遍历每个对象的条目并将它们推送到累加器中:

const data = [
  {
    "foo": {"name":"foo-name"},
    "bar": {"name":"bar-name"}
  },
  {
    "baz": {"name":"baz-name"}
  }
];

const output = data.reduce((a, obj) => {
  Object.entries(obj).forEach(([key, val]) => {
    a.push({ [key]: val });
  });
  return a;
}, []);
console.log(output);


1
谢谢你的点赞!在我看来,Code maniac的答案最为简洁明了,因此被选为最佳答案,但还是感谢你的回答! - DRNR

2
我会使用简单的for-of 循环和Object.entries映射到对象:
最初的回答:
const result = [];
for (const obj of data) {
    result.push(
        ...Object.entries(obj).map(
            ([key, value]) => ({[key]: value})
        )
    );
}

最初的回答:

实时示例:

const data = [
  {
    "foo": {"name":"foo-name"},
    "bar": {"name":"bar-name"}
  },
  {
    "baz": {"name":"baz-name"}
  }
];
const result = [];
for (const obj of data) {
    result.push(
        ...Object.entries(obj).map(
            ([key, value]) => ({[key]: value})
        )
    );
}
console.log(result);


顺便提一下:我们能否使用 concat 而不是 push,这样我们就不需要显式地展开了。 - Code Maniac
1
@CodeManiac - concat 会创建一个新的数组,所以这段代码会在各个地方创建新的数组。这就是为什么我使用了 push - T.J. Crowder
@T.J.Crowder 哦,这很有道理,也许是一个离题的问题,因为JS有GC,每次创建新数组与每次将值推入同一数组是否会受到影响? - Code Maniac
@CodeManiac - 会产生内存压力,这可能是性能问题的源头。但当然,这取决于代码是一次性运行还是多次运行。很有可能这并不重要。另外请注意,上面的理论上涉及创建一个对象(迭代器)以便为push展开数组,因此它似乎是一个零和方程(创建数组或创建迭代器)--除非JavaScript引擎在可以时优化掉该迭代器(如上所述)。如果我真的很担心并且不知道这一点,我会使用result.push.apply(result, /*...*/)。 :-D - T.J. Crowder
这个push解决方案仅适用于最多约30k条目的数组。(我假设OP的对象没有超过30k个属性。) 在此之后,您会在V8上运行出栈。 - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接