我有一个数组:
[{
name: "A1"
series: "A series"
},
{
name: "A2"
series: "A series"
},
{
name: "B1"
series: "B series"
},
{
name: "C1"
// series is not defined
}]
我想将此数组拆分为多个数组,这些数组按series属性的值分组。我想得出以下结构。但是,只要结果包含按其series属性值分组的数组,确切的格式就无关紧要。
[
{
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编译器的抱怨。
问题:
在adigas评论后编辑
答案 0 :(得分:1)
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)
};
});
}
答案 1 :(得分:-1)
您可以编写一个通用函数来接受任何字段并按它们分组。诸如此类的内容可能会有所帮助。
data = [{
name: "A1",
series: "A series"
},
{
name: "A2",
series: "A series"
},
{
name: "B1",
series: "B series"
},
{
name: "C1",
// series is not defined
}]
data1 = [{
name: "A",
series: "A series"
},
{
name: "A",
series: "A series"
},
{
name: "B",
series: "B series"
},
{
name: "C",
// series is not defined
}]
function groupByField(data, field){
const groupedByObject = data.reduce((acc, val) => {
const rest = Object.keys(val).reduce((newObj, key) => {
if(key !== field){
newObj[key] = val[key]
}
return newObj;
}, {});
if (acc[val[field]]) {
acc[val[field]].push(rest);
} else {;
acc[val[field]] = [rest];
}
return acc;
}, {})
//Return the reduced object from above if want in Object format. If wanted array, return the below statement
return Object.keys(groupedByObject).filter(a => a!== "undefined").map(key => ({[field]: key, items: groupedByObject[key]}))
}
a = groupByField(data,"series");
console.log("Grouped by series")
console.log(a);
b = groupByField(data1, "name");
console.log("Grouped by name")
console.log(b);
答案 2 :(得分:-1)
我将遍历每个对象的name
和series
属性,如果series
默认为空字符串(如果为空),则将值放在其属性为{ {1}}被迭代,并且该系列的关联对象(带有嵌套的series
数组)。如果尚不存在序列,请根据需要创建它(并在必要时分配一个items
属性),否则只需将series
推入该序列即可。
最后,获取对象的值以获得所需的输出:
{ name }
翻译成Javascript:
const arr = [
{
name: 'A1',
series: 'A series',
},
{
name: 'A2',
series: 'A series',
},
{
name: 'B1',
series: 'B series',
},
{
name: 'C1',
// series is not defined
},
];
type outputItem = {
series?: string,
items: Array<{ name: string }>,
};
const groupedObj: { [series: string]: outputItem } = {};
for (const { name, series='' } of arr) {
if (!groupedObj[series]) {
groupedObj[series] = { items: [{ name }] };
if (series) {
groupedObj[series].series = series;
}
} else {
groupedObj[series].items.push({ name });
}
}
const output = Object.values(groupedObj);
console.log(output);
不过,该对象结构非常独特。使用键为"use strict";
const arr = [
{
name: 'A1',
series: 'A series',
},
{
name: 'A2',
series: 'A series',
},
{
name: 'B1',
series: 'B series',
},
{
name: 'C1',
},
];
const groupedObj = {};
for (const { name, series = '' } of arr) {
if (!groupedObj[series]) {
groupedObj[series] = { items: [{ name }] };
if (series) {
groupedObj[series].series = series;
}
}
else {
groupedObj[series].items.push({ name });
}
}
const output = Object.values(groupedObj);
console.log(output);
且值是series
值数组的单个对象可能会容易得多:
name
翻译成Javascript:
const arr = [
{
name: 'A1',
series: 'A series',
},
{
name: 'A2',
series: 'A series',
},
{
name: 'B1',
series: 'B series',
},
{
name: 'C1',
// series is not defined
},
];
const output: { [series: string]: string[] } = {};
for (const { name, series='' } of arr) {
if (!output[series]) {
output[series] = [name];
} else {
output[series].push(name);
}
}
console.log(output);