将嵌套对象转换为数组

3

我有一个包含其他对象的对象,例如:

let foo = {
  a: {
    b: {},
    c: {}
  },
  d: {
    e: {}
  }
};

现在我想将其转换为对象数组,其中前两个级别的键形成键/值对,例如:
let transformedFoo = [
  { outer: 'a', inner: 'b' },
  { outer: 'a', inner: 'c' },
  { outer: 'd', inner: 'e' }
];

我的当前方法如下:

let fooTransformed = [];

Object.keys(foo).forEach(function (outerKey) {
  Object.keys(foo[outerKey]).forEach(function (innerKey) {
    fooTransformed.push({
      outer: outerKey,
      inner: innerKey
    });
  });
});

它可以工作,但我认为它不够"优美"(即有两个嵌套循环不太好)。有没有更好的方法来实现这个(我可以想象出一种相当优雅的纯函数解决方案,但我想不到任何一个)?


2
看起来你的方法是被接受的。链接 - PM 77-1
2
从逻辑上讲,嵌套操作需要另一个嵌套循环(或条件语句)。"函数式"方法只需隐藏此事实即可。 - David Pullar
1
@DavidPullar是正确的,你需要一个嵌套的map,再加上一个reduce来展开结果。请参见下面的链接:https://dev59.com/Pofca4cB1Zd3GeqPhE0p#28179747 - tlehman
1个回答

2

使用 map 和 reduce 函数:

> Object.keys(foo).map(function(key) { 
      return Object.keys(foo[key]).map(function(val) {
          return {outer: key, inner: val} } ) 
      }).reduce(function(a,b) { return a.concat(b) })

[ { outer: 'a', inner: 'b' },
  { outer: 'a', inner: 'c' },
  { outer: 'd', inner: 'e' } ]

2
如果你将第一个map和最后一个reduce结合起来,你可以改进这个程序并保留原先的两个循环。 return reduced.concat(Object.keys(foo[key]).map(function(val) { return {outer: key, inner: val} } )) }, []);``` - lemieuxster
1
它能够正常工作,而且是一种功能性的方法,因此我接受了它并点赞了。不过,无论如何,我还是会坚持我的原始版本的;-) - Golo Roden
尝试并查看其他方法是否提供了真正有益的东西是很好的。你的方法更清晰地说明了正在发生的事情。 - tlehman

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