首页 > 解决方案 > 如何根据某个属性的值将元素数组拆分为组?

问题描述

我有一个数组:

[{
    name: "A1"
    series: "A series"
}, 
{
    name: "A2"
    series: "A series"
}, 
{
    name: "B1"
    series: "B series"
}, 
{
    name: "C1"
    // series is not defined
}]

我想将此数组拆分为多个数组,这些数组按它们的系列属性值分组。我想得到类似下面的结构。但只要结果包含按系列属性的值分组的数组,确切的格式就无关紧要。

[
    {
        series: "A series",
        items: [{
            name: "A1"
        },
        {
            name: "A2"
        }]
    },
    {
        series: "B series",
        items: [{
            name: "B1"
        }]
    }
    {
        items: [{
            name: "C1"
        }]
    }
]

这是我最好的尝试:

private groupProductsBySeries = (devices: IItem[]): IProductGroup[] => {
    const seriesSymbols: any = new Map();
    const itemsBySeries: any = [];
    const series: any = [];

    devices.forEach((device) => {
        let symbol = seriesSymbols.get(device.properties.series);
        if (!symbol) {
            symbol = Symbol();
            seriesSymbols.set(device.properties.series, symbol);
        }

        Array.isArray(itemsBySeries[symbol])
            ? itemsBySeries[symbol].push(device)
            : (itemsBySeries[symbol] = [device]);
    });

    seriesSymbols.forEach((value: any, key: any) => {
        series.push({
            name: key,
            items: itemsBySeries[value],
        });
    });

    return series;
};

我在想,这可能是不必要的复杂。当我尝试添加类型时,我会收到来自 TypeScript 编译器的抱怨。

问题:

在阿迪加斯评论后编辑

标签: javascripttypescript

解决方案


function groupProductsBySeries(devices) {
  const series = Array.from(new Set(devices.map(item => item.series)));
  return series.map(item => {
    const series = item ? { series: item } : null;

    return {
      ...series,
      items: devices.filter(device => device.series === item)
    };
  });
}

推荐阅读