两个数组对象比较

let arr= [
    {key: '1', options: ['a', 'b', 'c'], value: 'a'},
    {key: '2', options: [], value: ''},
    {key: '3', options: ['d','e','f'], value: 'd'},
]
let arr= [
    {key: '1', options: [], value: ''},
    {key: '4', options: [], value: ''},
    {key: '5', options: [], value: ''},
    {key: '6', options: [], value: ''},
]

比较两个数组对象,合并成一个新数组

let newArr = [
    {key: '1', options: ['a', 'b', 'c'], value: 'a'},
    {key: '2', options: [], value: ''},
    {key: '3', options: ['d','e','f'], value: 'd'},
    {key: '4', options: [], value: ''},
    {key: '5', options: [], value: ''},
    {key: '6', options: [], value: ''},
]

最好使用es6 怎么实现

阅读 5.3k
5 个回答
function concat(arr1, arr2) {
  const uniq = arr => [...new Set(arr)];
  const getOptions = arr => arr.reduce((p, i) => [...p, ...i.options], []);
  const getValue = arr => arr.reduce((p, i) => p + i.value, "");
  const keys = [...arr1, ...arr2].map(it => it.key);

  return uniq(keys).reduce((pre, key) => {
    const a1 = arr1.filter(it => it.key === key);
    const a2 = arr2.filter(it => it.key === key);
    return [...pre, {
      key,
      options: [...getOptions(a1), ...getOptions(a2)],
      value: getValue(a1) + getValue(a2)
    }];

  }, []);
}

-----补充-----

题主提出需要合并的字段可能要增加。

费了点脑细胞搞了个配置化的方法。?

function concat(arr1, arr2, merger = {}) {
  const uniq = arr => [...new Set(arr)];
  const keys = [...arr1, ...arr2].map(it => it.key);

  return uniq(keys).reduce((pre, key) => {
    const a1 = arr1.filter(it => it.key === key);
    const a2 = arr2.filter(it => it.key === key);

    const item = Object.keys(merger)
      .reduce((pre, key) => ({
        ...pre,
        // 用外部传入的合并函数合并两个入参数组的累加值
        [key]: merger[key](
          // 第一个合并函数用于合并reduce传入的上次循环返回值与当次循环的值
          // 第二个合并函数用于获取reduce的默认值
          a1.reduce((p, i) => merger[key](p, i[key]), merger[key]()),
          a2.reduce((p, i) => merger[key](p, i[key]), merger[key]()),
        )
      }), {});

    return [...pre, {
      key,
      ...item,
    }];

  }, []);
}

// 第三个参数是一个合并器,它的key值将用于生成新数组的成员。
// 它的值是一个合并函数,用于合并入参中对应字段,同时该函数需要提供reduce的起始默认值
const newList = concat(arr1, arr2, {
  options: (v1, v2) => v1 ? [...v1, ...v2] : [],
  value: (v1, v2) => v1 ? v1 + v2 : ""
});

提供一种思路:

let newarr = arr.map(item=> {let newarr = arr.map(item => {
    const i = arr2.find(x => item.key === x.key);
    if (i === undefined) return item
    i.options = [...i.options, ...item.options]
    i.value = i.value == '' ? i.value + item.value : i.value + ',' + item.value
    return i
}).concat(arr2)
var newArr = [...new Set(newarr)]
console.log(newArr, 2);
//[{"key":"1","options":["d","e","a","b","c"],"value":"c,a"},{"key":"2","options":[],"value":""},{"key":"3","options":["oo","d","e","f"],"value":"h,d"},{"key":"4","options":[],"value":""},{"key":"5","options":[],"value":""}] 2

给一个思路吧:

  1. 声明空对象let info = {},用于存key到key所在对象的映射。
  2. 遍历数组1,将每一项item存放到info中: info[item.key]=item
  3. 遍历数组2,对于每一项item,判断如果没有info[item.key],则直接存入info: info[item.key]=item;如果有info[item.key],则将info[item.key]和item对options和values进行合并。
  4. 遍历对象info,把每一个值存入数组,数组即为所求。
let newArr = arr.concat(arr2)

这不是很简单的吗...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题