合并数组中的key值.md 4.1 KB

在js中合并两个数组中key值相同的项

前言

风和日丽的一天,群里突然抛出一个问题,现在有一个数组,其中有多个项的key属性是一样的,现在需要进行合并 示例代码结构

// 输入的数据
const arr = [
    {key: 1, a: 'a'},
    {key: 1, b: 'b'},
    {key: 2, a: 'a'},
    {key: 2, b: 'b', c: 'c'},
    {key: 3, a: 'a', b: 'b'},
    {key: 4, a: 'a', b: 'b'},
]

需要的结果

// 需要的结果
const arr_res = [
    {key: 1, a: 'a', b: 'b'},
    {key: 2, a: 'a', b: 'b', c: 'c'},
    {key: 3, a: 'a', b: 'b'},
    {key: 4, a: 'a', b: 'b'},
]

解决方案

[!tip] 记录了大佬们的回答,都是用的上面的数据以及变量,测试下方代码需要连同上方代码一起复制

使用reduce进行处理

罗老师版本

这个版本为湿鸡老师所写

var obj = arr.reduce((_,o)=>{
    _[o.key] ? (_[o.key] = Object.assign(_[o.key],o)) : (_[o.key] = o);return _;
},{})
var a = [];
for( var key in obj ){
    a.push(obj[key])
}

console.log(a);

用reduce循环将key作为累加值的键,用Object.assign来处理key值相同的项. 最后使用数组转换为

群宠晨晨大佬的一行版本

这个版本,为大佬所写,过于高端.和湿鸡老师写的有所不同,虽然同样是使用reduce,但是我特么一下真的看不懂. 但是大佬有另一个版本

arr.reduce((r, o) => ((r[o.key] = {...r[o.key], ...o}), r), []).filter(i => i)

在这个版本大佬看见数据结构的key值是用数字组成的,可以转换为数组下标

晨晨大佬的一行版本扩写

// 晨晨大佬一行版本修改
let x2 = arr.reduce((r,o)=>{
    // 通过解构进行合并不同的项
    r[o.key] = {...r[o.key], ...o}
    return r
},[])
// 因为key值不是百分百都对应数组的下标.所以用filter过滤
x2 = x2.filter(i=>i)
console.log(x2);

其他方式处理

[!tip] 其他的解决方法

晨晨大佬的mapFor版本

const map = new Map()
let crt
for (const item of arr) {
    crt = map.get(item.key)
    map.set(item.key, {...crt, ...item})
}
const res = [...map.values()]

使用map来替代对象,对象不好转化为数组,map的values函数可以返回所有的值

知识点总结

1. reduce的使用,MDN详细文档

在js里,为array进行了部分扩展,reduce函数将会将数组中的每个元素执行你所提供的reduce回调函数,返回指定值

[!tip] 这个函数中callback函数接收的参数和其他的数组函数基本一致,除了第一个参数有所不同,后续参数基本一致

  1. 参数解释
  2. callback要执行的函数
  3. initValue初始值

    // @param {Function} callback 要执行的函数
    // @param {*} initValue 初始值.可选默认为 undefined
    Array.reduce(callback,initValue)
    
  4. callback函数可以接收的参数

  5. accumulator累加器,上次循环的返回值,如果是第一次循环,则值为initValue.

  6. currentValue当前值,当前循环到的数组元素的实际值

  7. index下标,当前循环到的数组元素的下标值

  8. array原始数组,当前循环的原始数组 [!tip] 一个偏向于官方风格的示例,用来求数组中的和

执行下方代码

let result = [0,1,2,3].reduce((accumulator,currentValue,index,array)=>{
    console.log(`accumulator:${accumulator}\ncurrentValue:${currentValue}\nindex:${index}\n`)
    return accumulator + currentValue
},-1)
console.log(`最后返回的值${result}`)

控制台输出

accumulator:-1
currentValue:0
index:0

accumulator:-1
currentValue:1
index:1

accumulator:0
currentValue:2
index:2

accumulator:2
currentValue:3
index:3

最后返回的值5

2. js解构赋值

3. Map的使用