JavaScript如何實(shí)現(xiàn)數(shù)組按屬性分組
在JavaScript中,有多種方法可以對(duì)數(shù)組按屬性進(jìn)行分組。以下是至少6種常見的方法:
6種方法的使用場(chǎng)景和優(yōu)缺點(diǎn)的簡(jiǎn)要描述
1.使用reduce()方法
使用場(chǎng)景:適用于需要對(duì)數(shù)組進(jìn)行聚合操作的情況,可以自定義聚合邏輯。
優(yōu)點(diǎn):靈活性高,可以自定義聚合邏輯;可以同時(shí)對(duì)多個(gè)屬性進(jìn)行分組。
缺點(diǎn):代碼相對(duì)復(fù)雜,需要熟悉reduce()方法的使用。
2.使用forEach()方法:
使用場(chǎng)景:適用于簡(jiǎn)單的分組需求,不需要自定義聚合邏輯。
優(yōu)點(diǎn):簡(jiǎn)單易懂,代碼量較少。
缺點(diǎn):無法同時(shí)對(duì)多個(gè)屬性進(jìn)行分組;不支持鏈?zhǔn)讲僮鳌?/p>
3.使用map()方法和Object.create(null):
使用場(chǎng)景:適用于需要?jiǎng)?chuàng)建一個(gè)純凈的空對(duì)象作為分組結(jié)果的情況。
優(yōu)點(diǎn):可以創(chuàng)建一個(gè)沒有原型鏈的空對(duì)象,避免可能的屬性沖突。
缺點(diǎn):相對(duì)于使用普通對(duì)象,性能稍差。
4.使用Map對(duì)象:
使用場(chǎng)景:適用于需要對(duì)分組結(jié)果進(jìn)行進(jìn)一步操作的情況,如遍歷、刪除、更新等。
優(yōu)點(diǎn):支持對(duì)分組結(jié)果進(jìn)行靈活的操作;可以同時(shí)對(duì)多個(gè)屬性進(jìn)行分組。
缺點(diǎn):相對(duì)于普通對(duì)象,Map對(duì)象的性能稍差。
5.使用lodash庫的groupBy()方法:
使用場(chǎng)景:適用于使用lodash庫的項(xiàng)目,或者需要使用其他lodash庫的功能。
優(yōu)點(diǎn):簡(jiǎn)單易用,代碼量少;lodash庫提供了豐富的其他功能。
缺點(diǎn):引入了額外的庫,增加了項(xiàng)目的依賴。
6.使用ES6的Map和箭頭函數(shù):
使用場(chǎng)景:適用于需要使用ES6的特性,或者需要對(duì)分組結(jié)果進(jìn)行進(jìn)一步操作的情況。
優(yōu)點(diǎn):支持對(duì)分組結(jié)果進(jìn)行靈活的操作;可以同時(shí)對(duì)多個(gè)屬性進(jìn)行分組;使用了ES6的特性。
缺點(diǎn):相對(duì)于普通對(duì)象,Map對(duì)象的性能稍差。
根據(jù)具體的需求和項(xiàng)目環(huán)境,選擇適合的方法可以提高代碼的可讀性和性能。對(duì)于簡(jiǎn)單的分組需求,可以選擇forEach()方法或lodash庫的groupBy()方法;對(duì)于復(fù)雜的分組需求,可以選擇reduce()方法、Map對(duì)象或ES6的Map和箭頭函數(shù)。
1.使用reduce()方法封裝的方法
這種方法使用reduce()方法來對(duì)數(shù)組進(jìn)行迭代,并根據(jù)指定的屬性值將元素分組。它使用一個(gè)空對(duì)象作為初始值,然后在迭代過程中,根據(jù)屬性值將元素添加到相應(yīng)的分組中。
- 首先創(chuàng)建一個(gè)空對(duì)象,用于存儲(chǔ)分組結(jié)果。
- 使用for循環(huán)遍歷數(shù)組中的每個(gè)元素。
- 在每次迭代中,使用if語句檢查當(dāng)前元素的屬性值是否已經(jīng)存在于分組對(duì)象中。
- 如果屬性值不存在,就創(chuàng)建一個(gè)新的屬性,并將當(dāng)前元素添加到該屬性對(duì)應(yīng)的數(shù)組中。
- 如果屬性值已經(jīng)存在,就將當(dāng)前元素添加到該屬性對(duì)應(yīng)的數(shù)組中。
- 最后返回分組對(duì)象。
使用示例:
const arr = [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
];
const result = groupByReduce(arr, 'age');
console.log(result);輸出結(jié)果:
{
'20': [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Charlie', age: 20, gender: 'male' }
],
'25': [
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
],
'30': [
{ name: 'David', age: 30, gender: 'male' }
]
}
2.使用forEach()方法封裝的方法
這種方法使用forEach()方法對(duì)數(shù)組進(jìn)行迭代,并根據(jù)指定的屬性值將元素分組。它使用一個(gè)空對(duì)象作為初始值,然后在迭代過程中,根據(jù)屬性值將元素添加到相應(yīng)的分組中。
- 使用reduce方法對(duì)數(shù)組進(jìn)行迭代,并傳入一個(gè)初始值為空對(duì)象。
- 在每次迭代中,使用初始值作為累加器,并根據(jù)當(dāng)前元素的屬性值,將元素添加到相應(yīng)的屬性數(shù)組中。
- 最后返回累加器,即分組結(jié)果。
使用示例:
const arr = [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
];
const result = groupByForEach(arr, 'gender');
console.log(result);輸出結(jié)果:
{
female: [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Eve', age: 25, gender: 'female' }
],
male: [
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' }
]
}
3.使用map()方法和Object.create(null)封裝的方法
這種方法使用map()方法對(duì)數(shù)組進(jìn)行迭代,并根據(jù)指定的屬性值將元素分組。它使用Object.create(null)創(chuàng)建一個(gè)沒有原型的空對(duì)象作為初始值,然后在迭代過程中,根據(jù)屬性值將元素添加到相應(yīng)的分組中。
- 創(chuàng)建一個(gè)空的Map對(duì)象,用于存儲(chǔ)分組結(jié)果。
- 使用forEach方法對(duì)數(shù)組進(jìn)行迭代。
- 在每次迭代中,根據(jù)當(dāng)前元素的屬性值,使用Map對(duì)象的get方法獲取對(duì)應(yīng)的屬性數(shù)組。
- 如果屬性數(shù)組不存在,就創(chuàng)建一個(gè)新的屬性數(shù)組,并將當(dāng)前元素添加到該數(shù)組中。
- 如果屬性數(shù)組已經(jīng)存在,就將當(dāng)前元素添加到該數(shù)組中。
- 最后將分組結(jié)果轉(zhuǎn)換為普通對(duì)象,并返回。
使用示例:
const arr = [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
];
const result = groupByMap(arr, 'age');
console.log(result);輸出結(jié)果:
{
'20': [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Charlie', age: 20, gender: 'male' }
],
'25': [
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
],
'30': [
{ name: 'David', age: 30, gender: 'male' }
]
}
4.使用Map對(duì)象封裝的方法
這種方法使用Map對(duì)象來存儲(chǔ)分組結(jié)果。它使用forEach()方法對(duì)數(shù)組進(jìn)行迭代,并根據(jù)指定的屬性值將元素分組。在迭代過程中,根據(jù)屬性值將元素添加到相應(yīng)的分組中,并使用Map對(duì)象的set()方法來保存分組結(jié)果。
- 創(chuàng)建一個(gè)空的Map對(duì)象,用于存儲(chǔ)分組結(jié)果。
- 使用forEach方法對(duì)數(shù)組進(jìn)行迭代。
- 在每次迭代中,使用箭頭函數(shù)來根據(jù)當(dāng)前元素的屬性值,將元素添加到相應(yīng)的屬性數(shù)組中。
- 最后將分組結(jié)果轉(zhuǎn)換為普通對(duì)象,并返回。
使用示例:
const arr = [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
];
const result = groupByMapObj(arr, 'gender');
console.log(result);輸出結(jié)果:
{
female: [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Eve', age: 25, gender: 'female' }
],
male: [
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' }
]
}
5.使用lodash庫的groupBy()方法封裝的方法
這種方法使用lodash庫的groupBy()方法來實(shí)現(xiàn)分組。它接受一個(gè)數(shù)組和一個(gè)屬性名作為參數(shù),并返回一個(gè)對(duì)象,其中鍵是屬性值,值是具有相同屬性值的元素?cái)?shù)組。
- 使用lodash庫的groupBy方法,傳入數(shù)組和屬性名作為參數(shù)。
- groupBy方法會(huì)根據(jù)屬性值將數(shù)組元素分組,并返回一個(gè)對(duì)象,其中鍵是屬性值,值是具有相同屬性值的元素?cái)?shù)組。
- 返回分組結(jié)果
使用示例:
const arr = [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
];
const result = groupByLodash(arr, 'age');
console.log(result);輸出結(jié)果:
{
'20': [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Charlie', age: 20, gender: 'male' }
],
'25': [
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
],
'30': [
{ name: 'David', age: 30, gender: 'male' }
]
}
6.使用ES6的Map和箭頭函數(shù)封裝的方法
這種方法使用ES6的Map對(duì)象來存儲(chǔ)分組結(jié)果。它使用forEach()方法對(duì)數(shù)組進(jìn)行迭代,并根據(jù)指定的屬性值將元素分組。在迭代過程中,根據(jù)屬性值將元素添加到相應(yīng)的分組中,并使用Map對(duì)象的set()方法來保存分組結(jié)果。
- 創(chuàng)建一個(gè)空的Map對(duì)象,用于存儲(chǔ)分組結(jié)果。
- 使用forEach方法對(duì)數(shù)組進(jìn)行迭代。
- 在每次迭代中,使用箭頭函數(shù)來根據(jù)當(dāng)前元素的屬性值,將元素添加到相應(yīng)的屬性數(shù)組中。
- 最后將分組結(jié)果轉(zhuǎn)換為普通對(duì)象,并返回。
使用示例:
const arr = [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
];
const result = groupByMapArrow(arr, 'gender');
console.log(result);輸出結(jié)果:
{
female: [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Eve', age: 25, gender: 'female' }
],
male: [
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' }
]
}
以上是六種不同的方法的詳細(xì)說明和使用示例。根據(jù)需求和個(gè)人喜好,可以選擇適合的方法來進(jìn)行分組操作。
7.試著封裝起來
以下是將這6種方法封裝
function groupBy(arr, prop, method) {
switch (method) {
case 'reduce':
return arr.reduce((result, item) => {
const key = item[prop];
if (!result[key]) {
result[key] = [];
}
result[key].push(item);
return result;
}, {});
case 'forEach':
const grouped = {};
arr.forEach(item => {
const key = item[prop];
if (!grouped[key]) {
grouped[key] = [];
}
grouped[key].push(item);
});
return grouped;
case 'map':
const grouped = Object.create(null);
arr.map(item => {
const key = item[prop];
if (!grouped[key]) {
grouped[key] = [];
}
grouped[key].push(item);
});
return grouped;
case 'mapObj':
const grouped = new Map();
arr.forEach(item => {
const key = item[prop];
const group = grouped.get(key) || [];
group.push(item);
grouped.set(key, group);
});
return Object.fromEntries(grouped);
case 'lodash':
const _ = require('lodash');
return _.groupBy(arr, prop);
case 'mapArrow':
const grouped = new Map();
arr.forEach(item => {
const key = item[prop];
const group = grouped.get(key) || [];
group.push(item);
grouped.set(key, group);
});
return Object.fromEntries(grouped);
default:
return {};
}
}使用示例:
const arr = [
{ name: 'Alice', age: 20, gender: 'female' },
{ name: 'Bob', age: 25, gender: 'male' },
{ name: 'Charlie', age: 20, gender: 'male' },
{ name: 'David', age: 30, gender: 'male' },
{ name: 'Eve', age: 25, gender: 'female' }
];
???????console.log(groupBy(arr, 'age', 'reduce'));
console.log(groupBy(arr, 'gender', 'forEach'));
console.log(groupBy(arr, 'age', 'map'));
console.log(groupBy(arr, 'gender', 'mapObj'));
console.log(groupBy(arr, 'age', 'lodash'));
console.log(groupBy(arr, 'gender', 'mapArrow'));封裝后,可以根據(jù)傳入的方法名調(diào)用相應(yīng)的分組方法,方便調(diào)用和切換不同的分組方法。
到此這篇關(guān)于JavaScript如何實(shí)現(xiàn)數(shù)組按屬性分組的文章就介紹到這了,更多相關(guān)JavaScript數(shù)組分組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript的變量聲明與聲明提前用法實(shí)例分析
這篇文章主要介紹了JavaScript的變量聲明與聲明提前用法,結(jié)合實(shí)例形式分析了JavaScript變量聲明與聲明提前相關(guān)原理、用法及操作注意事項(xiàng),需要的朋友可以參考下2019-11-11
JavaScript Array.flat()函數(shù)用法解析
這篇文章主要介紹了JavaScript Array.flat()函數(shù)用法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
JS操作select下拉框動(dòng)態(tài)變動(dòng)(創(chuàng)建/刪除/獲取)
動(dòng)態(tài)創(chuàng)建及刪除select、添加及刪除選項(xiàng)option、獲得選項(xiàng)option的值、獲得選項(xiàng)option的文本等等,感興趣的朋友可以參考下哈2013-06-06
NestJS使用class-validator進(jìn)行數(shù)據(jù)驗(yàn)證
本文將通過詳細(xì)的步驟和實(shí)戰(zhàn)技巧,帶大家掌握如何在NestJS中使用class-validator進(jìn)行數(shù)據(jù)驗(yàn)證,以及11條實(shí)戰(zhàn)中常用的驗(yàn)證技巧,感興趣的可以了解下2024-11-11
setInterval計(jì)時(shí)器不準(zhǔn)的問題解決方法
在js中如果打算使用setInterval進(jìn)行倒數(shù),計(jì)時(shí)等功能,往往是不準(zhǔn)確的,針對(duì)這個(gè)問題,本文有個(gè)不錯(cuò)的解決方案2014-05-05
javascript定時(shí)器取消定時(shí)器及優(yōu)化方法
這篇文章主要介紹了 javascript定時(shí)器取消定時(shí)器及js定時(shí)器優(yōu)化方法的相關(guān)資料,需要的朋友可以參考下2017-07-07

