JavaScript如何實(shí)現(xiàn)數(shù)組按屬性分組
在JavaScript中,有多種方法可以對(duì)數(shù)組按屬性進(jìn)行分組。以下是至少6種常見(jiàn)的方法:
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):無(wú)法同時(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è)沒(méi)有原型鏈的空對(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庫(kù)的groupBy()方法:
使用場(chǎng)景:適用于使用lodash庫(kù)的項(xiàng)目,或者需要使用其他lodash庫(kù)的功能。
優(yōu)點(diǎn):簡(jiǎn)單易用,代碼量少;lodash庫(kù)提供了豐富的其他功能。
缺點(diǎn):引入了額外的庫(kù),增加了項(xiàng)目的依賴(lài)。
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庫(kù)的groupBy()方法;對(duì)于復(fù)雜的分組需求,可以選擇reduce()方法、Map對(duì)象或ES6的Map和箭頭函數(shù)。
1.使用reduce()方法封裝的方法
這種方法使用reduce()方法來(lái)對(duì)數(shù)組進(jìn)行迭代,并根據(jù)指定的屬性值將元素分組。它使用一個(gè)空對(duì)象作為初始值,然后在迭代過(guò)程中,根據(jù)屬性值將元素添加到相應(yīng)的分組中。
- 首先創(chuàng)建一個(gè)空對(duì)象,用于存儲(chǔ)分組結(jié)果。
- 使用for循環(huán)遍歷數(shù)組中的每個(gè)元素。
- 在每次迭代中,使用if語(yǔ)句檢查當(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ì)象作為初始值,然后在迭代過(guò)程中,根據(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è)沒(méi)有原型的空對(duì)象作為初始值,然后在迭代過(guò)程中,根據(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ì)象來(lái)存儲(chǔ)分組結(jié)果。它使用forEach()方法對(duì)數(shù)組進(jìn)行迭代,并根據(jù)指定的屬性值將元素分組。在迭代過(guò)程中,根據(jù)屬性值將元素添加到相應(yīng)的分組中,并使用Map對(duì)象的set()方法來(lái)保存分組結(jié)果。
- 創(chuàng)建一個(gè)空的Map對(duì)象,用于存儲(chǔ)分組結(jié)果。
- 使用forEach方法對(duì)數(shù)組進(jìn)行迭代。
- 在每次迭代中,使用箭頭函數(shù)來(lái)根據(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庫(kù)的groupBy()方法封裝的方法
這種方法使用lodash庫(kù)的groupBy()方法來(lái)實(shí)現(xiàn)分組。它接受一個(gè)數(shù)組和一個(gè)屬性名作為參數(shù),并返回一個(gè)對(duì)象,其中鍵是屬性值,值是具有相同屬性值的元素?cái)?shù)組。
- 使用lodash庫(kù)的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ì)象來(lái)存儲(chǔ)分組結(jié)果。它使用forEach()方法對(duì)數(shù)組進(jìn)行迭代,并根據(jù)指定的屬性值將元素分組。在迭代過(guò)程中,根據(jù)屬性值將元素添加到相應(yīng)的分組中,并使用Map對(duì)象的set()方法來(lái)保存分組結(jié)果。
- 創(chuàng)建一個(gè)空的Map對(duì)象,用于存儲(chǔ)分組結(jié)果。
- 使用forEach方法對(duì)數(shù)組進(jìn)行迭代。
- 在每次迭代中,使用箭頭函數(shù)來(lái)根據(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ì)說(shuō)明和使用示例。根據(jù)需求和個(gè)人喜好,可以選擇適合的方法來(lái)進(jìn)行分組操作。
7.試著封裝起來(lái)
以下是將這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-11JavaScript Array.flat()函數(shù)用法解析
這篇文章主要介紹了JavaScript Array.flat()函數(shù)用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09JS操作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-06NestJS使用class-validator進(jìn)行數(shù)據(jù)驗(yàn)證
本文將通過(guò)詳細(xì)的步驟和實(shí)戰(zhàn)技巧,帶大家掌握如何在NestJS中使用class-validator進(jìn)行數(shù)據(jù)驗(yàn)證,以及11條實(shí)戰(zhàn)中常用的驗(yàn)證技巧,感興趣的可以了解下2024-11-11微信小程序云開(kāi)發(fā) 搭建一個(gè)管理小程序
這篇文章主要為大家詳細(xì)介紹了微信小程序云開(kāi)發(fā),搭建一個(gè)管理小程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05setInterval計(jì)時(shí)器不準(zhǔn)的問(wèn)題解決方法
在js中如果打算使用setInterval進(jìn)行倒數(shù),計(jì)時(shí)等功能,往往是不準(zhǔn)確的,針對(duì)這個(gè)問(wèn)題,本文有個(gè)不錯(cuò)的解決方案2014-05-05javascript定時(shí)器取消定時(shí)器及優(yōu)化方法
這篇文章主要介紹了 javascript定時(shí)器取消定時(shí)器及js定時(shí)器優(yōu)化方法的相關(guān)資料,需要的朋友可以參考下2017-07-07