如何生成按键分组的对象数组

How to produce an array of objects grouped by key

给定一个对象数组,这些对象具有一些共同属性,如 foosWithBar,我如何在不使用 lodash 等库的情况下,创建另一个由这些共同属性(如 barsWithFoos)分组的对象数组?我发现 使用 reduce() 创建按键分组的对象,但这不是我想要的。

const foosWithBar = [
  {
    id: 'Foo A',
    bar: {
      id: 'Bar 1',
    },
  },
  {
    id: 'Foo B',
    bar: {
      id: 'Bar 1',
    },
  },
  {
    id: 'Foo C',
    bar: {
      id: 'Bar 2',
    },
  },
  {
    id: 'Foo D',
    bar: {
      id: 'Bar 2',
    },
  },
]

const barsWithFoos = [
  {
    id: 'Bar 1',
    foos: [
      {
        id: 'Foo A',
      },
      {
        id: 'Foo B',
      },
    ],
  },
  {
    id: 'Bar 2',
    foos: [
      {
        id: 'Foo C',
      },
      {
        id: 'Foo D',
      },
    ],
  },
]

迭代每个 foo 项目并在 barsWithFoos 数组中搜索它。如果不存在,您需要将其包含在 barsWithFoos.push({ id: foo.bar.id, foos: [] }) 中。然后只需将 foo 推入 bar 列表中 barsWithFoos[i - 1].foos.push({ id: foo.id }):

const foosWithBar = [  {id: 'Foo A',bar: { id: 'Bar 1', }, }, {    id: 'Foo B',    bar: {      id: 'Bar 1',    },  },  {    id: 'Foo C',   bar: {      id: 'Bar 2',    },  },  {   id: 'Foo D',   bar: {      id: 'Bar 2',    },  },];

const barsWithFoos = [];
foosWithBar.forEach(foo => {
  const i = barsWithFoos.findIndex(bar => bar.id === foo.bar.id) + 1 
            || barsWithFoos.push({ id:  foo.bar.id, foos: [] });
  barsWithFoos[i - 1].foos.push({ id: foo.id });
})

console.log(barsWithFoos);

使用 reduce 将其移动为新格式。使用一个对象来跟踪您已经引用的“条形图”。您比使用 Object.values 来获取数组。

const foosWithBar = [
  { id: 'Foo A', bar: { id: 'Bar 1', }, },
  { id: 'Foo B', bar: { id: 'Bar 1', }, },
  { id: 'Foo C', bar: { id: 'Bar 2', }, },
  { id: 'Foo D', bar: { id: 'Bar 2', }, },
];

const opposite = Object.values(
  foosWithBar.reduce(
    function(acc, item) {
      if (!acc[item.bar.id]) { // have we seen it yet?
        acc[item.bar.id] = { // if not create the object
          id: item.bar.id,
          foos: [{
            id: item.id
          }]
        };
      } else { // if we seen it, just add the new foo
        acc[item.bar.id].foos.push({
            id: item.id
        });
      }
      return acc;
    }, {})
);
console.log(opposite);