[英]Javascript transform array using reduce method
我正在尝试以如下形式转换一组对象:
const categories = [{
"category": "Category 1",
"desc": "Description 1 of the category 1"
},
{
"category": "Category 1",
"desc": "Description 2 of the category 1"
}, {
"category": "Category 2",
"desc": "Description 1 of the category 2"
},
{
"category": "Category 2",
"desc": "Description 2 of the category 2"
},
{
"category": "Category 3",
"desc": "Description 1 of the category 3"
}, {
"category": "Category 3",
"desc": "Description 2 of the category 3"
}
];
到表单(所需的结果集);
[
{
"category": "Category 1",
"desriptionList": [
{
"desc": "Description 1 of the category 1"
},
{
"desc": "Description 2 of the category 1"
}
]
},
{
"category": "Category 2",
"desriptionList": [
{
"error": "Description 1 of the category 2"
},
{
"error": "Description 2 of the category 2"
},
]
},
{
"category": "Category 3",
"desriptionList": [
{
"error": "Description 1 of the category 3"
},
{
"error": "Description 2 of the category 3"
},
]
}
]
使用reduce
方法:
const result = categories.reduce((acc, item) => {
return [{
...acc,
'category': item.category,
'desriptionList': item.desc
}]
}, [])
但似乎我以错误的方式在错误的地方使用了累加器,因为有一个奇怪的输出;
[{
0: {
0: { ... },
category: "Category 3",
desriptionList: "Description 1 of the category 3"
},
category: "Category 3",
desriptionList: "Description 2 of the category 3"
}]
保持简单并使用 Array.reduce() 和 Array.findIndex 遍历每个对象并决定是否应将其数据添加到累加器中的现有对象,或者是否应创建并推送新对象。
const categories=[{category:"Category 1",desc:"Description 1 of the category 1"},{category:"Category 1",desc:"Description 2 of the category 1"},{category:"Category 2",desc:"Description 1 of the category 2"},{category:"Category 2",desc:"Description 2 of the category 2"},{category:"Category 3",desc:"Description 1 of the category 3"},{category:"Category 3",desc:"Description 2 of the category 3"}]; const result = categories.reduce(( acc, cur ) => { let idx = acc.findIndex( obj => obj.category === cur.category ) if( idx > -1 ) { acc[idx].descriptionList.push(cur.desc) } else { acc.push( { category: cur.category, descriptionList: [ cur.desc ] } ) } return acc }, []) console.log(result)
"!target.descriptionList.includes(curr)" 条件确保每个类别没有重复的 desc。 如果您觉得没有必要,请随意删除它。
const categories = [{
"category": "Category 1",
"desc": "Description 1 of the category 1"
},
{
"category": "Category 1",
"desc": "Description 2 of the category 1"
}, {
"category": "Category 2",
"desc": "Description 1 of the category 2"
},
{
"category": "Category 2",
"desc": "Description 2 of the category 2"
},
{
"category": "Category 3",
"desc": "Description 1 of the category 3"
}, {
"category": "Category 3",
"desc": "Description 2 of the category 3"
}
];
const newArr = categories.reduce((acc, curr) => {
let target = acc.find(element => element.category === curr.category);
if (target) {
if (!target.descriptionList.includes(curr)) {
delete curr.category;
target.descriptionList.push(curr);
}
} else {
acc.push({
category: curr.category,
descriptionList: [{ desc: curr.desc }]
})
}
return acc
}, []);
console.log('newArr: ' + JSON.stringify(newArr));
输出
newArr: [
{
"category": "Category 1",
"descriptionList": [
{
"desc": "Description 1 of the category 1"
},
{
"desc": "Description 2 of the category 1"
}
]
},
{
"category": "Category 2",
"descriptionList": [
{
"desc": "Description 1 of the category 2"
},
{
"desc": "Description 2 of the category 2"
}
]
},
{
"category": "Category 3",
"descriptionList": [
{
"desc": "Description 1 of the category 3"
},
{
"desc": "Description 2 of the category 3"
}
]
}
]
由于您需要使用将desc
分组到类别,因此您将使用一个对象作为累加器。 在每次迭代中,将累加器 ( acc
) 扩展到一个新对象中,并添加当前category
。
要创建或更新类别的对象,请添加category
,并传播该category
先前实例( undefined
被忽略),添加desriptionList
,并传播先前的desriptionList
(如果没有,则为后备),并添加当前的desc
项。
使用Object.values()
转换为数组。
const categories = [{"category":"Category 1","desc":"Description 1 of the category 1"},{"category":"Category 1","desc":"Description 2 of the category 1"},{"category":"Category 2","desc":"Description 1 of the category 2"},{"category":"Category 2","desc":"Description 2 of the category 2"},{"category":"Category 3","desc":"Description 1 of the category 3"},{"category":"Category 3","desc":"Description 2 of the category 3"}]; const result = Object.values(categories.reduce((acc, { category, desc }) => ({ ...acc, [category]: { ...acc[category], category, desriptionList: [ ...(acc[category]?.desriptionList || []), { desc } ] } }), {})) console.log(result)
另一种选择是将类别分组为 Map,然后使用Array.from()
将 Map 转换为数组。
const categories = [{"category":"Category 1","desc":"Description 1 of the category 1"},{"category":"Category 1","desc":"Description 2 of the category 1"},{"category":"Category 2","desc":"Description 1 of the category 2"},{"category":"Category 2","desc":"Description 2 of the category 2"},{"category":"Category 3","desc":"Description 1 of the category 3"},{"category":"Category 3","desc":"Description 2 of the category 3"}]; const result = Array.from( categories.reduce((acc, { category, desc }) => { if (!acc.has(category)) acc.set(category, []); // initialize the category with an empty array acc.get(category).push({ desc }) // push current desc into the array return acc; }, new Map()), ([category, desriptionList]) => ({ category, desriptionList }) // convert to an array ) console.log(result)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.