[英]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.