输入:数组,函数/属性
输出:对象,其中key
:数组所有元素经过处理后的值,value
:相同key的数组元素集合
eg:输入[6.1,4.2,6.3],Math.floor
输出{4: [4.2], 6: [6.1,6.3]}
输入:['one','two','three'],'length'
输出:{3:['one','two'], 5:['three']}
法1:map+reduce
reduce()
方法对数组中的每个元素执行用户定义的reduce
函数
arr.reduce(function(prev,cur,index,arr){
...
}, init);
prev
必需。上一次调用回调时的返回值,或者初始值init
;cur
必需。表示当前正在处理的数组元素;index
可选。表示当前正在处理的数组元素的索引,若提供init
值,则起始索引为0
,否则起始索引为1
;简单来说就是,不设置init,则从第二个元素开始循环,设置了就从第一个开始循环,pre就是initarr
可选。表示原数组;init
可选。表示初始值。
function groupBy(arr, fn) {
return arr.map(item => {
if (typeof fn === 'function') {
return fn(item)
} else {
return item[fn]
}
}).reduce((pre, cur, index) => {
// pre的初始值为{}
if (!pre[cur]) {
pre[cur] = [arr[index]]
} else {
pre[cur] = [...pre[cur], arr[index]]
}
return pre
}, {})
}
let arr1 = ['one', 'two', 'three']
console.log(groupBy(arr1, 'length'))
let arr2 = [6.1, 4.2, 6.3]
console.log(groupBy(arr2, Math.floor))
法2:使用字典map
function groupBy(arr, fn) {
let map = new Map()
arr.forEach(item => {
let key = null
if (typeof fn === 'function') {
key = fn(item)
} else {
key = item[fn]
}
let value = item
if (map.has(key)) {
map.set(key, [...map.get(key), value])
} else {
map.set(key, [value])
}
})
let result = {}
for (let [key, value] of map) {
result[key] = value
}
return result
}
let arr1 = ['one', 'two', 'three']
console.log(groupBy(arr1, 'length'))
let arr2 = [6.1, 4.2, 6.3]
console.log(groupBy(arr2, Math.floor))
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。