对象数组 - 如何按 属性 对项目进行分组并将每个分组项目的数据压缩为 1
Array of objects - how to group items by property and squash data from each of grouped items into 1
我正在尝试对主题中描述的数组执行操作。
我已经完成的工作 - 按公共 属性 + 将每个项目的数据映射到所需格式进行分组。它是通过在其中使用 reduce + map 函数实现的。
现在我需要最后一部分将每个分组的项目属性压缩为 1。
我的目标是让它正常工作,最好是通过扩展重组功能。
要重构的数组
const arrToRestructure = [
{
x: "test-x1",
y: "test-y1",
data: [
{id: 1, label: "label-y1-1"},
{id: 2, label: "label-y1-2"}
]
},
{
x: "test-x2",
y: "test-y1",
data: [
{id: 1, label: "label-y1-3"},
{id: 2, label: "label-y1-4"}
]
},
{
x: "test-x2",
y: "test-y2",
data: [
{id: 1, label: "label-y2-1"},
{id: 2, label: "label-y2-2"}
]
},
]
重构函数
const restructureArr = () => {
const restructuredArr = arrToRestructure.reduce(
(prevVal, nextVal) => ({
...prevVal,
[nextVal["y"]]: [
...(prevVal[nextVal["y"]] || []),
nextVal.data.map((nextVal) => nextVal.label),
]})
,[]);
return restructuredArr;
}
当前输出
{
"test-y1": [
[
"label-y1-1",
"label-y1-2"
],
[
"label-y1-3",
"label-y1-4"
]
],
"test-y2": [
[
"label-y2-1",
"label-y2-2"
]
]
}
期望输出
{
"test-y1": [
"label-y1-1",
"label-y1-2",
"label-y1-3",
"label-y1-4",
],
"test-y2": [
"label-y2-1",
"label-y2-2"
]
}
每次简单地传播Array#map
结果:
const restructureArr = () => {
const restructuredArr = arrToRestructure.reduce((prevVal, nextVal) => ({
...prevVal,
[nextVal["y"]]: [
...(prevVal[nextVal["y"]] || []),
...nextVal.data.map((nextVal) => nextVal.label), // fix
]
}) , []);
return restructuredArr;
}
一些改进:
const restructureArr = (arrToRestructure = []) =>
arrToRestructure.reduce((acc, { y, data = [] }) => ({
...acc,
[y]: [
...(acc[y] || []),
...data.map(({ label }) => label),
]
}), []);
const arrToRestructure = [
{ x: "test-x1", y: "test-y1", data: [ {id: 1, label: "label-y1-1"}, {id: 2, label: "label-y1-2"} ] },
{ x: "test-x2", y: "test-y1", data: [ {id: 1, label: "label-y1-3"}, {id: 2, label: "label-y1-4"} ] },
{ x: "test-x2", y: "test-y2", data: [ {id: 1, label: "label-y2-1"}, {id: 2, label: "label-y2-2"} ] }
];
console.log(restructureArr(arrToRestructure));
您可以使用 array#reduce
根据 y
值进行分组。使用 array#forEach
.
推送相同 y
值的所有标签
const arrToRestructure = [ { x: "test-x1", y: "test-y1", data: [ {id: 1, label: "label-y1-1"}, {id: 2, label: "label-y1-2"} ] }, { x: "test-x2", y: "test-y1", data: [ {id: 1, label: "label-y1-3"}, {id: 2, label: "label-y1-4"} ] }, { x: "test-x2", y: "test-y2", data: [ {id: 1, label: "label-y2-1"}, {id: 2, label: "label-y2-2"} ] }, ],
result = arrToRestructure.reduce((r, {y, data}) => {
r[y] ??= [];
data.forEach(({label}) => r[y].push(label));
return r;
},{});
console.log(result);
另一种解决方案是使用 Object.entries
和 .flat()
。
const obj = { "test-y1": [ [ "label-y1-1", "label-y1-2" ], [ "label-y1-3", "label-y1-4" ] ], "test-y2": [ [ "label-y2-1", "label-y2-2" ] ] }
const e = Object.entries(obj).map(el => ({[el[0]]: el[1].flat()}))
let o = Object.fromEntries(e.map(x => [Object.keys(x), Object.values(x)[0]]))
console.log(o);
我正在尝试对主题中描述的数组执行操作。 我已经完成的工作 - 按公共 属性 + 将每个项目的数据映射到所需格式进行分组。它是通过在其中使用 reduce + map 函数实现的。 现在我需要最后一部分将每个分组的项目属性压缩为 1。 我的目标是让它正常工作,最好是通过扩展重组功能。
要重构的数组
const arrToRestructure = [
{
x: "test-x1",
y: "test-y1",
data: [
{id: 1, label: "label-y1-1"},
{id: 2, label: "label-y1-2"}
]
},
{
x: "test-x2",
y: "test-y1",
data: [
{id: 1, label: "label-y1-3"},
{id: 2, label: "label-y1-4"}
]
},
{
x: "test-x2",
y: "test-y2",
data: [
{id: 1, label: "label-y2-1"},
{id: 2, label: "label-y2-2"}
]
},
]
重构函数
const restructureArr = () => {
const restructuredArr = arrToRestructure.reduce(
(prevVal, nextVal) => ({
...prevVal,
[nextVal["y"]]: [
...(prevVal[nextVal["y"]] || []),
nextVal.data.map((nextVal) => nextVal.label),
]})
,[]);
return restructuredArr;
}
当前输出
{
"test-y1": [
[
"label-y1-1",
"label-y1-2"
],
[
"label-y1-3",
"label-y1-4"
]
],
"test-y2": [
[
"label-y2-1",
"label-y2-2"
]
]
}
期望输出
{
"test-y1": [
"label-y1-1",
"label-y1-2",
"label-y1-3",
"label-y1-4",
],
"test-y2": [
"label-y2-1",
"label-y2-2"
]
}
每次简单地传播Array#map
结果:
const restructureArr = () => {
const restructuredArr = arrToRestructure.reduce((prevVal, nextVal) => ({
...prevVal,
[nextVal["y"]]: [
...(prevVal[nextVal["y"]] || []),
...nextVal.data.map((nextVal) => nextVal.label), // fix
]
}) , []);
return restructuredArr;
}
一些改进:
const restructureArr = (arrToRestructure = []) =>
arrToRestructure.reduce((acc, { y, data = [] }) => ({
...acc,
[y]: [
...(acc[y] || []),
...data.map(({ label }) => label),
]
}), []);
const arrToRestructure = [
{ x: "test-x1", y: "test-y1", data: [ {id: 1, label: "label-y1-1"}, {id: 2, label: "label-y1-2"} ] },
{ x: "test-x2", y: "test-y1", data: [ {id: 1, label: "label-y1-3"}, {id: 2, label: "label-y1-4"} ] },
{ x: "test-x2", y: "test-y2", data: [ {id: 1, label: "label-y2-1"}, {id: 2, label: "label-y2-2"} ] }
];
console.log(restructureArr(arrToRestructure));
您可以使用 array#reduce
根据 y
值进行分组。使用 array#forEach
.
y
值的所有标签
const arrToRestructure = [ { x: "test-x1", y: "test-y1", data: [ {id: 1, label: "label-y1-1"}, {id: 2, label: "label-y1-2"} ] }, { x: "test-x2", y: "test-y1", data: [ {id: 1, label: "label-y1-3"}, {id: 2, label: "label-y1-4"} ] }, { x: "test-x2", y: "test-y2", data: [ {id: 1, label: "label-y2-1"}, {id: 2, label: "label-y2-2"} ] }, ],
result = arrToRestructure.reduce((r, {y, data}) => {
r[y] ??= [];
data.forEach(({label}) => r[y].push(label));
return r;
},{});
console.log(result);
另一种解决方案是使用 Object.entries
和 .flat()
。
const obj = { "test-y1": [ [ "label-y1-1", "label-y1-2" ], [ "label-y1-3", "label-y1-4" ] ], "test-y2": [ [ "label-y2-1", "label-y2-2" ] ] }
const e = Object.entries(obj).map(el => ({[el[0]]: el[1].flat()}))
let o = Object.fromEntries(e.map(x => [Object.keys(x), Object.values(x)[0]]))
console.log(o);