JavaScript如何實現(xiàn)數(shù)組按屬性分組
在JavaScript中,有多種方法可以對數(shù)組按屬性進行分組。以下是至少6種常見的方法:
6種方法的使用場景和優(yōu)缺點的簡要描述
1.使用reduce()方法
使用場景:適用于需要對數(shù)組進行聚合操作的情況,可以自定義聚合邏輯。
優(yōu)點:靈活性高,可以自定義聚合邏輯;可以同時對多個屬性進行分組。
缺點:代碼相對復雜,需要熟悉reduce()方法的使用。
2.使用forEach()方法:
使用場景:適用于簡單的分組需求,不需要自定義聚合邏輯。
優(yōu)點:簡單易懂,代碼量較少。
缺點:無法同時對多個屬性進行分組;不支持鏈式操作。
3.使用map()方法和Object.create(null):
使用場景:適用于需要創(chuàng)建一個純凈的空對象作為分組結果的情況。
優(yōu)點:可以創(chuàng)建一個沒有原型鏈的空對象,避免可能的屬性沖突。
缺點:相對于使用普通對象,性能稍差。
4.使用Map對象:
使用場景:適用于需要對分組結果進行進一步操作的情況,如遍歷、刪除、更新等。
優(yōu)點:支持對分組結果進行靈活的操作;可以同時對多個屬性進行分組。
缺點:相對于普通對象,Map對象的性能稍差。
5.使用lodash庫的groupBy()方法:
使用場景:適用于使用lodash庫的項目,或者需要使用其他lodash庫的功能。
優(yōu)點:簡單易用,代碼量少;lodash庫提供了豐富的其他功能。
缺點:引入了額外的庫,增加了項目的依賴。
6.使用ES6的Map和箭頭函數(shù):
使用場景:適用于需要使用ES6的特性,或者需要對分組結果進行進一步操作的情況。
優(yōu)點:支持對分組結果進行靈活的操作;可以同時對多個屬性進行分組;使用了ES6的特性。
缺點:相對于普通對象,Map對象的性能稍差。
根據(jù)具體的需求和項目環(huán)境,選擇適合的方法可以提高代碼的可讀性和性能。對于簡單的分組需求,可以選擇forEach()方法或lodash庫的groupBy()方法;對于復雜的分組需求,可以選擇reduce()方法、Map對象或ES6的Map和箭頭函數(shù)。
1.使用reduce()方法封裝的方法
這種方法使用reduce()方法來對數(shù)組進行迭代,并根據(jù)指定的屬性值將元素分組。它使用一個空對象作為初始值,然后在迭代過程中,根據(jù)屬性值將元素添加到相應的分組中。
- 首先創(chuàng)建一個空對象,用于存儲分組結果。
- 使用for循環(huán)遍歷數(shù)組中的每個元素。
- 在每次迭代中,使用if語句檢查當前元素的屬性值是否已經(jīng)存在于分組對象中。
- 如果屬性值不存在,就創(chuàng)建一個新的屬性,并將當前元素添加到該屬性對應的數(shù)組中。
- 如果屬性值已經(jīng)存在,就將當前元素添加到該屬性對應的數(shù)組中。
- 最后返回分組對象。
使用示例:
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);
輸出結果:
{
'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()方法對數(shù)組進行迭代,并根據(jù)指定的屬性值將元素分組。它使用一個空對象作為初始值,然后在迭代過程中,根據(jù)屬性值將元素添加到相應的分組中。
- 使用reduce方法對數(shù)組進行迭代,并傳入一個初始值為空對象。
- 在每次迭代中,使用初始值作為累加器,并根據(jù)當前元素的屬性值,將元素添加到相應的屬性數(shù)組中。
- 最后返回累加器,即分組結果。
使用示例:
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);
輸出結果:
{
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()方法對數(shù)組進行迭代,并根據(jù)指定的屬性值將元素分組。它使用Object.create(null)創(chuàng)建一個沒有原型的空對象作為初始值,然后在迭代過程中,根據(jù)屬性值將元素添加到相應的分組中。
- 創(chuàng)建一個空的Map對象,用于存儲分組結果。
- 使用forEach方法對數(shù)組進行迭代。
- 在每次迭代中,根據(jù)當前元素的屬性值,使用Map對象的get方法獲取對應的屬性數(shù)組。
- 如果屬性數(shù)組不存在,就創(chuàng)建一個新的屬性數(shù)組,并將當前元素添加到該數(shù)組中。
- 如果屬性數(shù)組已經(jīng)存在,就將當前元素添加到該數(shù)組中。
- 最后將分組結果轉(zhuǎn)換為普通對象,并返回。
使用示例:
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);
輸出結果:
{
'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對象封裝的方法
這種方法使用Map對象來存儲分組結果。它使用forEach()方法對數(shù)組進行迭代,并根據(jù)指定的屬性值將元素分組。在迭代過程中,根據(jù)屬性值將元素添加到相應的分組中,并使用Map對象的set()方法來保存分組結果。
- 創(chuàng)建一個空的Map對象,用于存儲分組結果。
- 使用forEach方法對數(shù)組進行迭代。
- 在每次迭代中,使用箭頭函數(shù)來根據(jù)當前元素的屬性值,將元素添加到相應的屬性數(shù)組中。
- 最后將分組結果轉(zhuǎn)換為普通對象,并返回。
使用示例:
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);
輸出結果:
{
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()方法來實現(xiàn)分組。它接受一個數(shù)組和一個屬性名作為參數(shù),并返回一個對象,其中鍵是屬性值,值是具有相同屬性值的元素數(shù)組。
- 使用lodash庫的groupBy方法,傳入數(shù)組和屬性名作為參數(shù)。
- groupBy方法會根據(jù)屬性值將數(shù)組元素分組,并返回一個對象,其中鍵是屬性值,值是具有相同屬性值的元素數(shù)組。
- 返回分組結果
使用示例:
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);
輸出結果:
{
'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對象來存儲分組結果。它使用forEach()方法對數(shù)組進行迭代,并根據(jù)指定的屬性值將元素分組。在迭代過程中,根據(jù)屬性值將元素添加到相應的分組中,并使用Map對象的set()方法來保存分組結果。
- 創(chuàng)建一個空的Map對象,用于存儲分組結果。
- 使用forEach方法對數(shù)組進行迭代。
- 在每次迭代中,使用箭頭函數(shù)來根據(jù)當前元素的屬性值,將元素添加到相應的屬性數(shù)組中。
- 最后將分組結果轉(zhuǎn)換為普通對象,并返回。
使用示例:
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);
輸出結果:
{
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' }
]
}
以上是六種不同的方法的詳細說明和使用示例。根據(jù)需求和個人喜好,可以選擇適合的方法來進行分組操作。
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)用相應的分組方法,方便調(diào)用和切換不同的分組方法。
到此這篇關于JavaScript如何實現(xiàn)數(shù)組按屬性分組的文章就介紹到這了,更多相關JavaScript數(shù)組分組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JavaScript Array.flat()函數(shù)用法解析
這篇文章主要介紹了JavaScript Array.flat()函數(shù)用法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09JS操作select下拉框動態(tài)變動(創(chuàng)建/刪除/獲取)
動態(tài)創(chuàng)建及刪除select、添加及刪除選項option、獲得選項option的值、獲得選項option的文本等等,感興趣的朋友可以參考下哈2013-06-06NestJS使用class-validator進行數(shù)據(jù)驗證
本文將通過詳細的步驟和實戰(zhàn)技巧,帶大家掌握如何在NestJS中使用class-validator進行數(shù)據(jù)驗證,以及11條實戰(zhàn)中常用的驗證技巧,感興趣的可以了解下2024-11-11