Lodash 的又一方法被替代了,探索 JS 新特性 Object.groupBy
Hello,大家好,我是 Sunday。
ES 2024增加了很多 JS 的新特性, 在這篇文章中 我們也提到過幾個(gè)可能會(huì)大火的新方法。
其中 Object.groupBy 是最受大家關(guān)注的新方法之一:
Object.groupBy() 靜態(tài)方法根據(jù)提供的回調(diào)函數(shù)返回的字符串值對(duì)給定可迭代對(duì)象中的元素進(jìn)行分組。返回的對(duì)象具有每個(gè)組的單獨(dú)屬性,其中包含組中的元素的數(shù)組。
它的具體語法如下所示:
Object.groupBy(items, callbackFn)
// array:需要分組的數(shù)組。
// callback:對(duì)數(shù)組中的每個(gè)元素執(zhí)行的回調(diào)函數(shù)。回調(diào)函數(shù)返回一個(gè)值,用作分組的鍵。
而這樣方法在 Lodash 中也有過類似的實(shí)現(xiàn),作用也與 Object.groupBy 類似(如果我們關(guān)注最近幾年的 ES 新增特性,會(huì)發(fā)現(xiàn)很多的新增特性都在社區(qū)庫中提前進(jìn)行過實(shí)現(xiàn)):
圖片
那么接下來就讓我們通過 5 個(gè)場(chǎng)景,深入看一下 Object.groupBy 這個(gè)方法,對(duì)我們以后的開發(fā)會(huì)有什么幫助!
01:按單一條件分組
按照年齡為數(shù)據(jù)進(jìn)行分組。
const users = [
{ name: '張三', age: 21 },
{ name: '李四', age: 25 },
{ name: '王五', age: 21 },
{ name: '趙六', age: 28 }
]
const groupedByAge = Object.groupBy(users, (user) => user.age)
console.log(groupedByAge)
/*
{
"21": [
{
"name": "張三",
"age": 21
},
{
"name": "王五",
"age": 21
}
],
"25": [
{
"name": "李四",
"age": 25
}
],
"28": [
{
"name": "趙六",
"age": 28
}
]
}
*/
02:按多個(gè)條件分組
const users = [
{ name: '張三', age: 21, gender: '男' },
{ name: '李四', age: 25, gender: '女' },
{ name: '王五', age: 21, gender: '女' },
{ name: '趙六', age: 25, gender: '女' },
{ name: '孫七', age: 30, gender: '女' },
{ name: '周八', age: 21, gender: '男' }
]
const groupedByAgeAndGender = Object.groupBy(users, (user) => {
const ageGroup = user.age < 25 ? '25歲以下' : '25歲以上'
return `${ageGroup}-${user.gender}`
})
console.log(groupedByAgeAndGender)
/*
{
"25歲以下-男": [
{
"name": "張三",
"age": 21,
"gender": "男"
},
{
"name": "周八",
"age": 21,
"gender": "男"
}
],
"25歲以上-女": [
{
"name": "李四",
"age": 25,
"gender": "女"
},
{
"name": "趙六",
"age": 25,
"gender": "女"
},
{
"name": "孫七",
"age": 30,
"gender": "女"
}
],
"25歲以下-女": [
{
"name": "王五",
"age": 21,
"gender": "女"
}
]
}
*/
03:按復(fù)雜計(jì)算分組
根據(jù)指定的結(jié)果對(duì)數(shù)據(jù)進(jìn)行分組處理。
const students = [
{ name: '張三', score: 85 },
{ name: '李四', score: 92 },
{ name: '王五', score: 70 },
{ name: '趙六', score: 78 },
{ name: '孫七', score: 88 }
]
const groupedByGrade = Object.groupBy(students, (student) => {
if (student.score >= 90) return 'A'
if (student.score >= 80) return 'B'
if (student.score >= 70) return 'C'
return 'D'
})
console.log(groupedByGrade)
/*
{
"B": [
{
"name": "張三",
"score": 85
},
{
"name": "孫七",
"score": 88
}
],
"A": [
{
"name": "李四",
"score": 92
}
],
"C": [
{
"name": "王五",
"score": 70
},
{
"name": "趙六",
"score": 78
}
]
}
*/
04:依賴另外的數(shù)據(jù)進(jìn)行分組
假設(shè)我們有一個(gè)用戶數(shù)據(jù)數(shù)組,并且想要按用戶居住的城市對(duì)其進(jìn)行分組,其中城市數(shù)據(jù)是從外部 API 獲取的。
const users = [
{ name: '張三', cityId: 1 },
{ name: '李四', cityId: 2 },
{ name: '王五', cityId: 1 },
{ name: '趙六', cityId: 3 },
{ name: '孫七', cityId: 2 }
]
// Simulate fetching city data from an external API
const cityData = {
1: '北京',
2: '上海',
3: '深圳'
}
const groupedByCity = Object.groupBy(users, (user) => cityData[user.cityId])
console.log(groupedByCity)
/*
{
"北京": [
{
"name": "張三",
"cityId": 1
},
{
"name": "王五",
"cityId": 1
}
],
"上海": [
{
"name": "李四",
"cityId": 2
},
{
"name": "孫七",
"cityId": 2
}
],
"深圳": [
{
"name": "趙六",
"cityId": 3
}
]
}
*/
05:按日期分組
根據(jù)日期進(jìn)行數(shù)據(jù)劃分。
const logs = [
{ message: '時(shí)間1', date: '2024-01-01T10:00:00Z' },
{ message: '時(shí)間2', date: '2024-01-01T12:00:00Z' },
{ message: '時(shí)間3', date: '2024-01-02T10:00:00Z' },
{ message: '時(shí)間4', date: '2024-01-02T14:00:00Z' },
{ message: '時(shí)間5', date: '2024-01-03T10:00:00Z' }
]
const groupedByDate = Object.groupBy(
logs,
(log) => new Date(log.date).toISOString().split('T')[0]
)
console.log(groupedByDate)
/*
{
"2024-01-01": [
{
"message": "時(shí)間1",
"date": "2024-01-01T10:00:00Z"
},
{
"message": "時(shí)間2",
"date": "2024-01-01T12:00:00Z"
}
],
"2024-01-02": [
{
"message": "時(shí)間3",
"date": "2024-01-02T10:00:00Z"
},
{
"message": "時(shí)間4",
"date": "2024-01-02T14:00:00Z"
}
],
"2024-01-03": [
{
"message": "時(shí)間5",
"date": "2024-01-03T10:00:00Z"
}
]
}
*/
總結(jié)
結(jié)合以上的 5 個(gè)場(chǎng)景,我們可以看出 Object.groupBy 主要用來處理 分組 相關(guān)的操作。預(yù)期對(duì)應(yīng)的還有 Map.groupBy() 這個(gè)方法,他們的使用場(chǎng)景相差不大,這里就不去細(xì)說了。
所以,有了 Object.groupBy 之后,一旦遇到 分組 相關(guān)的場(chǎng)景,那就是用它吧~