[英]Sort and group an array of objects by two keys and create array of grouped items with new keys
我有以下數組:
const items = [
{ name: 'john', class: 'one', section: 'a' },
{ name: 'john2', class: 'one', section: 'b' },
{ name: 'john3', class: 'one', section: 'a' },
{ name: 'john4', class: 'two', section: 'a' },
{ name: 'john5', class: 'two', section: 'b' },
{ name: 'john6', class: 'two', section: 'b' },
{ name: 'john7', class: 'three', section: 'a' },
{ name: 'john8', class: 'four', section: 'a' },
{ name: 'john9', class: 'four', section: 'b' }
];
我想讓它以這種方式分組:
[
{
'oneA': [
{ name: 'john', class: 'one', section: 'a' },
{ name: 'john3', class: 'one', section: 'a' }
]
},
{
'oneB': [
{ name: 'john2', class: 'one', section: 'b' }
]
},
{
'twoA': [
{ name: 'john4', class: 'two', section: 'a' }
]
},
{
'twoB': [
{ name: 'john5', class: 'two', section: 'b' },
{ name: 'john6', class: 'two', section: 'b' }
]
},
{
'threeA': [
{ name: 'john7', class: 'three', section: 'a' }
]
},
{
'fourA': [
{ name: 'john8', class: 'four', section: 'a' }
]
},
{
'fourB': [
{ name: 'john9', class: 'four', section: 'b' }
]
}
]
我試過這樣的事情:
items.sort(function (a, b) {
if (a.class > b.class) return 1;
if (a.class < b.class) return -1;
if (a.section > b.section) return 1;
if (a.section < b.section) return -1;
})
這按照我的需要對數組進行排序,但它不像我上面描述的那樣分組。 你知道一種方法嗎?
您可以通過使用Map
它們分組。
它生成一個class
和大寫section
的鍵,嘗試從映射中獲取值或獲取一個空數組以將實際對象傳播到一個新數組中。 然后它將此數組設置為地圖中的新值。
Array.from
從映射中獲取所有鍵/值對,並使用計算屬性 name構建新對象。
const getKey = o => `${o.class}${o.section.toUpperCase()}`, items = [{ name: 'john', class: 'one', section: 'a' }, { name: 'john2', class: 'one', section: 'b' }, { name: 'john3', class: 'one', section: 'a' }, { name: 'john4', class: 'two', section: 'a' }, { name: 'john5', class: 'two', section: 'b' }, { name: 'john6', class: 'two', section: 'b' }, { name: 'john7', class: 'three', section: 'a' }, { name: 'john8', class: 'four', section: 'a' }, { name: 'john9', class: 'four', section: 'b' }], result = Array.from( items.reduce( (m, o) => m.set(getKey(o), [...(m.get(getKey(o)) || []), o]), new Map ), ([k, v]) => ({ [k]: v }) ); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
const items = [
{ name: 'john', class: 'one', section: 'a' },
{ name: 'john2', class: 'one', section: 'b' },
{ name: 'john3', class: 'one', section: 'a' },
{ name: 'john4', class: 'two', section: 'a' },
{ name: 'john5', class: 'two', section: 'b' },
{ name: 'john6', class: 'two', section: 'b' },
{ name: 'john7', class: 'three', section: 'a' },
{ name: 'john8', class: 'four', section: 'a' },
{ name: 'john9', class: 'four', section: 'b' }
];
let newArray = items.reduce((main, curr) => {
let index = main.findIndex(obj => Object.keys(obj).includes(curr.class + curr.section))
if (index == -1) main.push({ [curr.class + curr.section]: [curr] })
else main[index][curr.class + curr.section].push(curr)
return main
}, [])
console.log(newArray)
我建議省略結果的外部數組,因為對我來說,如果您想創建一組對象,那么擁有它是沒有意義的。
要解決您的問題,只需遍歷所有項目並檢查您的結果對象是否已具有所需的鍵。 如果沒有,則創建它,然后將當前項插入到相應的數組中。
const items = [ { name: 'john', class: 'one', section: 'a' }, { name: 'john2', class: 'one', section: 'b' }, { name: 'john3', class: 'one', section: 'a' }, { name: 'john4', class: 'two', section: 'a' }, { name: 'john5', class: 'two', section: 'b' }, { name: 'john6', class: 'two', section: 'b' }, { name: 'john7', class: 'three', section: 'a' }, { name: 'john8', class: 'four', section: 'a' }, { name: 'john9', class: 'four', section: 'b' } ]; let result = {}; items.forEach(item => { let key = `${item.class}${item.section.toUpperCase()}`; if(!result.hasOwnProperty(key)) { result[key] = []; } result[key].push(item); }); console.info(result);
您可以使用reduce
函數,例如:
const items = [ { name: 'john', class: 'one', section: 'a' }, { name: 'john2', class: 'one', section: 'b' }, { name: 'john3', class: 'one', section: 'a' }, { name: 'john4', class: 'two', section: 'a' }, { name: 'john5', class: 'two', section: 'b' }, { name: 'john6', class: 'two', section: 'b' }, { name: 'john7', class: 'three', section: 'a' }, { name: 'john8', class: 'four', section: 'a' }, { name: 'john9', class: 'four', section: 'b' } ]; const groupedItems = items.reduce((result, current) => { const key = current.class + current.section.toUpperCase(); if (Array.isArray(result[key])) { result[key].push(current); } else { result[key] = [current]; } return result; }, {}); const expectedResult = Array.from(Object.keys(groupedItems), (elem) => ({[elem]: groupedItems[elem]})); console.log(expectedResult);
如果您希望在不使用內置函數的情況下更好地理解純 javascript 的答案。
var items = [
{ name: 'john', class: 'one', section: 'a' },
{ name: 'john2', class: 'one', section: 'b' },
{ name: 'john3', class: 'one', section: 'a' },
{ name: 'john4', class: 'two', section: 'a' },
{ name: 'john5', class: 'two', section: 'b' },
{ name: 'john6', class: 'two', section: 'b' },
{ name: 'john7', class: 'three', section: 'a' },
{ name: 'john8', class: 'four', section: 'a' },
{ name: 'john9', class: 'four', section: 'b' }
];
var resultArray =[];
for(var i=0;i<items.length;i++){
if(resultArray[items[i]['class']+items[i]['section'].toUpperCase()]){
resultArray[items[i]['class']+items[i]['section'].toUpperCase()].push(items[i]);
} else {
var a ="";
a = items[i]['class']+items[i]['section'].toUpperCase();
resultArray[a]=[];
resultArray[a].push(items[i])
}
}
console.log(resultArray);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.