gpt4 book ai didi

Javascript 按特定顺序按多个属性递归分组和数组

转载 作者:行者123 更新时间:2023-12-01 01:34:21 25 4
gpt4 key购买 nike

我正在构建一个网格组件,该组件允许用户进行多行分组。

我正在处理的原始数据是库存商品的示例:

let stock = [
{ order: "200", type: "production", qty: 200, item: "IT282" },
{ order: "200", type: "production", qty: 90, item: "IT283" },
{ order: "200", type: "customer", qty: 80, item: "IT102" },
{ order: "200", type: "production", qty: 110, item: "IT283" },
{ order: "200", type: "customer", qty: 130, item: "IT102" },
{ order: "200", type: "production", qty: 45, item: "IT233" },
{ order: "200", type: "stock", qty: 30, item: "IT282" },
{ order: "210", type: "production", qty: 300, item: "IT282" },
{ order: "210", type: "production", qty: 190, item: "IT283" },
{ order: "210", type: "customer", qty: 180, item: "IT102" },
{ order: "210", type: "production", qty: 210, item: "IT283" },
{ order: "210", type: "customer", qty: 230, item: "IT102" },
{ order: "210", type: "production", qty: 145, item: "IT233" },
{ order: "210", type: "stock", qty: 130, item: "IT282" }
];

我需要完成的是能够使用多个字段以不同的顺序对数据进行分组,如下结果:

let result = groupBy(stock, ["order"]);

[
{
field: "order",
value: "200",
rows: [
{ order: "200", type: "production", qty: 200, item: "IT282" },
{ order: "200", type: "production", qty: 90, item: "IT283" },
{ order: "200", type: "customer", qty: 80, item: "IT102" },
{ order: "200", type: "production", qty: 110, item: "IT283" },
{ order: "200", type: "customer", qty: 130, item: "IT102" },
{ order: "200", type: "production", qty: 45, item: "IT233" },
{ order: "200", type: "stock", qty: 30, item: "IT282" }
]
},
{
field: "order",
value: "210",
rows: [
{ order: "210", type: "production", qty: 300, item: "IT282" },
{ order: "210", type: "production", qty: 190, item: "IT283" },
{ order: "210", type: "customer", qty: 180, item: "IT102" },
{ order: "210", type: "production", qty: 210, item: "IT283" },
{ order: "210", type: "customer", qty: 230, item: "IT102" },
{ order: "210", type: "production", qty: 145, item: "IT233" },
{ order: "210", type: "stock", qty: 130, item: "IT282" }
]
}
];

let result = groupBy(stock, ["item"]);

[
{
field: "item",
value: "IT282",
rows: [
{ order: "200", type: "production", qty: 200, item: "IT282" },
{ order: "200", type: "stock", qty: 30, item: "IT282" },
{ order: "210", type: "production", qty: 300, item: "IT282" },
{ order: "210", type: "stock", qty: 130, item: "IT282" }
]
},
{
field: "item",
value: "IT283",
rows: [
{ order: "200", type: "production", qty: 90, item: "IT283" },
{ order: "200", type: "production", qty: 110, item: "IT283" },
{ order: "210", type: "production", qty: 190, item: "IT283" },
{ order: "210", type: "production", qty: 210, item: "IT283" }
]
},
{
field: "item",
value: "IT102",
rows: [
{ order: "200", type: "customer", qty: 80, item: "IT102" },
{ order: "200", type: "customer", qty: 130, item: "IT102" },
{ order: "210", type: "customer", qty: 180, item: "IT102" },
{ order: "210", type: "customer", qty: 230, item: "IT102" }
]
},
{
field: "item",
value: "IT233",
rows: [
{ order: "200", type: "production", qty: 45, item: "IT233" },
{ order: "210", type: "production", qty: 145, item: "IT233" }
]
}
];

let result = groupBy(stock, ["order", "item"]);

[
{
field: "order",
value: "200",
rows: [
{
field: "item",
value: "IT282",
rows: [
{
order: "200",
type: "production",
qty: 200,
item: "IT282"
},
{ order: "200", type: "stock", qty: 30, item: "IT282" },
{
order: "210",
type: "production",
qty: 300,
item: "IT282"
}
]
},
{
field: "item",
value: "IT283",
rows: [
{
order: "200",
type: "production",
qty: 90,
item: "IT283"
},
{
order: "200",
type: "production",
qty: 110,
item: "IT283"
}
]
},
{
field: "item",
value: "IT102",
rows: [
{ order: "200", type: "customer", qty: 80, item: "IT102" },
{ order: "200", type: "customer", qty: 130, item: "IT102" }
]
},
{
field: "item",
value: "IT233",
rows: [
{
order: "200",
type: "production",
qty: 45,
item: "IT233"
}
]
}
]
},
{
field: "order",
value: "210",
rows: [
{
field: "item",
value: "IT282",
rows: [{ order: "210", type: "stock", qty: 130, item: "IT282" }]
},
{
field: "item",
value: "IT283",
rows: [
{
order: "210",
type: "production",
qty: 190,
item: "IT283"
},
{
order: "210",
type: "production",
qty: 210,
item: "IT283"
}
]
},
{
field: "item",
value: "IT102",
rows: [
{ order: "210", type: "customer", qty: 180, item: "IT102" },
{ order: "210", type: "customer", qty: 230, item: "IT102" }
]
},
{
field: "item",
value: "IT233",
rows: [
{
order: "210",
type: "production",
qty: 145,
item: "IT233"
}
]
}
]
}
];

let result = groupBy(stock, ["item", "order"]);

[
{
field: "item",
value: "IT282",
rows: [
{
field: "order",
value: "200",
rows: [
{
order: "200",
type: "production",
qty: 200,
item: "IT282"
},
{ order: "200", type: "stock", qty: 30, item: "IT282" }
]
},
{
field: "order",
value: "210",
rows: [
{
order: "210",
type: "production",
qty: 300,
item: "IT282"
},
{ order: "210", type: "stock", qty: 130, item: "IT282" }
]
}
]
},
{
field: "item",
value: "IT283",
rows: [
{
field: "order",
value: "200",
rows: [
{
order: "200",
type: "production",
qty: 90,
item: "IT283"
},
{
order: "200",
type: "production",
qty: 110,
item: "IT283"
}
]
},
{
field: "order",
value: "210",
rows: [
{
order: "210",
type: "production",
qty: 190,
item: "IT283"
},
{
order: "210",
type: "production",
qty: 210,
item: "IT283"
}
]
}
]
},
{
field: "item",
value: "IT102",
rows: [
{
field: "order",
value: "200",
rows: [
{ order: "200", type: "customer", qty: 80, item: "IT102" },
{ order: "200", type: "customer", qty: 130, item: "IT102" }
]
},
{
field: "order",
value: "210",
rows: [
{ order: "210", type: "customer", qty: 180, item: "IT102" },
{ order: "210", type: "customer", qty: 230, item: "IT102" }
]
}
]
},
{
field: "item",
value: "IT233",
rows: [
{
field: "order",
value: "200",
rows: [
{ order: "200", type: "production", qty: 45, item: "IT233" }
]
},
{
field: "order",
value: "210",
rows: [
{
order: "210",
type: "production",
qty: 145,
item: "IT233"
}
]
}
]
}
];

我的组函数将接收任何项目数组,并以任何顺序对任意数量的数组字段进行分组。

由于我想要一个基于 ES6 的函数,所以今天我使用 that link 中的以下 groupBy 函数这适用于单次传递,但我在嵌套在一起时遇到困难。

这是我正在处理的代码:

  groupBy = (rows, groups) => {
if (groups.length === 0) return rows;

return this.groupByField(rows, groups, 0);
};

groupByField = (rows, groups, index) => {
if (index >= groups.length) return rows;

let grouped = this.groupRows(rows, groups[index]);

index++;
let ret = [];

grouped.rows.map(row => {
ret.push(this.groupByField(row.rows, groups, index));
});

grouped.rows = ret;
return grouped;
};

groupRows = (rows, field) => {
return rows.reduce(function(groups, x) {
let val = helper.getValueByFieldNameString(x.data, field);

let found = groups.find(item => {
return item.groupedValue === val;
});

if (!found) {
let rows = [];
rows.push(x);

groups.push({
groupedField: field,
groupedValue: val,
rows: rows
});
} else {
found.rows.push(x);
}

return groups;
}, []);
};

似乎递归性无法正常工作。

最佳答案

我认为你可以创建一个使用reduceObject.values对数组进行分组的函数。然后,在对数组进行分组后,如果有更多字段可供分组,请在每个子 row 数组上调用该函数。例如:

let stock = [{ order: "200", type: "production", qty: 200, item: "IT282" },{ order: "200", type: "production", qty: 90, item: "IT283" },{ order: "200", type: "customer", qty: 80, item: "IT102" },{ order: "200", type: "production", qty: 110, item: "IT283" },{ order: "200", type: "customer", qty: 130, item: "IT102" },{ order: "200", type: "production", qty: 45, item: "IT233" },{ order: "200", type: "stock", qty: 30, item: "IT282" },{ order: "210", type: "production", qty: 300, item: "IT282" },{ order: "210", type: "production", qty: 190, item: "IT283" },{ order: "210", type: "customer", qty: 180, item: "IT102" },{ order: "210", type: "production", qty: 210, item: "IT283" },{ order: "210", type: "customer", qty: 230, item: "IT102" },{ order: "210", type: "production", qty: 145, item: "IT233" },{ order: "210", type: "stock", qty: 130, item: "IT282" }];

function groupBy(arr, fields) {
let field = fields[0] // one field at a time
if (!field) return arr
let retArr = Object.values(
arr.reduce((obj, current) => {
if (!obj[current[field]]) obj[current[field]] = {field: field, value: current[field],rows: []}
obj[current[field]].rows.push(current)
return obj
}, {}))

// recurse for each child's rows if there are remaining fields
if (fields.length){
retArr.forEach(obj => {
obj.count = obj.rows.length
obj.rows = groupBy(obj.rows, fields.slice(1))
})
}
return retArr
}

let result = groupBy(stock, ["order", "item"]);
console.log(result)

关于Javascript 按特定顺序按多个属性递归分组和数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52970177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com