开门见山,先看代码及运行结果
解释及代码如下:
当前存在以下数组
let list = [
{"name": "张三", "age": 15, "sex": '男'},
{"name": "张三", "age": 16, "sex": '女'},
{"name": "张三", "age": 17, "sex": '男'},
{"name": "李四", "age": 15, "sex": '女'},
{"name": "李四", "age": 16, "sex": '男'},
{"name": "李四", "age": 17, "sex": '女'}
]
如果想根据对象的某个属性,将该属性的值相同的对象分成一组,比如根据 name 属性,将该数组分成两组,name为张三的在一组,name为李四的在一组,该怎么实现呢 ?
如果对 java 比较熟悉的话,可能会想到java 中的 stream 操作,就有一个 groupBy函数,我们此时就可以利用 ES6 的 Map 结构实现一个自己的 groupBy函数,算是比较简洁的方法,具体代码如下
function groupBy(array, f) {
//初始化 Map, 用来存储键值对
let map = new Map()
array.forEach(function (obj) {
//根据传入的函数,对数组中的每一个对象产生一个 key值,并将key值相等的对象分为一组
let key = f(obj)
map.set(key, (map.get(key) || []) )
map.get(key).push(obj)
});
return map
}
该函数具体用法,及分组结果如下
let mapResult = groupBy( list, item => item.name)
console.log(mapResult)
函数原理解释:
该函数接收两个参数,第一个参数就是要分组的数组列表,第二个参数,则是一个函数,groupBy方法中,会对传入的数组的每一个对象调用一次该函数,然后根据该函数的返回结果,来决定要把这个对象分到哪一组中
而该函数最终会返回一个 Map 对象,如果想获得分组后的两个列表,可以使用 mapResult.get('张三')获得 name为张三的列表,也可以使用 mapResult.values() 和 ... 扩展符,获取分组结果的数组,这些都是可以自己根据 map 去自行处理的了