首页 > 解决方案 > 比较数组中的两个对象,删除重复数据,合并不同的数据?

问题描述

我得到一个数组中的对象列表,其中一些是重复的。但是,产生重复的条件是不同的。

所以想象一个数组:

var array = [{id: 1, name: 'test', condition: 'left'},
            {id: 2, name: 'example', condition: 'left'},
            {id: 1, name: 'test', condition: 'right'},
            {id: 3, name: 'foobar', condition: 'right'}]

我在找什么:

var solution = [{id: 1, name: 'test', condition: ['left', 'right']},
                {id: 2, name: 'example', condition: 'left'},
                {id: 3, name: 'foobar', condition: 'right'}]

我可以使用这种方法删除重复项没有问题:

var available = result.reduce((unique, o) => {
  if (!unique.some((obj) => obj.id === o.id && obj.name === o.name)) {
    unique.push(o);
  }
  return unique;
}, []);

但想结合条件数据

标签: javascriptarraysweb

解决方案


您可以分两步完成此操作。

  1. 按 id 分组数据
  2. 通过组合每个组的属性值来合并每个组的值

const array = [
  { id: 1 , name: 'test'    , condition: 'left'  },
  { id: 2 , name: 'example' , condition: 'left'  },
  { id: 1 , name: 'test'    , condition: 'right' },
  { id: 3 , name: 'foobar'  , condition: 'right' }
];

const groupBy = (key, objs) => objs.reduce((acc, obj) =>
  ({ ...acc, [obj[key]]: [...(acc[obj[key]] || []), obj] }), {});

const combine = (newVal, oldVal) =>
 oldVal != null
  ? Array.isArray(oldVal)
    ? !oldVal.includes(newVal)
      ? [ ...oldVal, newVal ]
      : oldVal
    : oldVal !== newVal
      ? [ oldVal, newVal ]
      : oldVal
  : newVal;

const merge = (objs) => objs.reduce((acc, obj) =>
  Object.keys(obj).reduce((acc1, key) =>
    ({ ...acc1, [key]: combine(obj[key], acc1[key]) }), acc), {});

const groupByAndMerge = (key, items) =>
  Object.values(groupBy(key, items)).map(merge);

console.log(groupByAndMerge('id', array));
.as-console-wrapper { top: 0; max-height: 100% !important; }

代码高尔夫

我将该函数简化为一个大小为 259 字节的单行语句。

// Size: 259 bytes
f=(k,a)=>Object.values(a.reduce((r,i)=>({...r,[i[k]]:[...(r[i[k]]||[]),i]}),{})).map(g=>g.reduce((s,o)=>Object.keys(o).reduce((t,m)=>({...t,[m]:t[m]!=null?Array.isArray(t[m])?!t[m].includes(o[m])?[...t[m],o[m]]:t[m]:t[m]!==o[m]?[t[m],o[m]]:t[m]:o[m]}),s),{}))

console.log(f('id',[{id:1,name:'test',condition:'left'},{id:2,name:'example',condition:'left'},{id:1,name:'test',condition:'right'},{id:3,name:'foobar',condition:'right'}]));
.as-console-wrapper { top: 0; max-height: 100% !important; }


推荐阅读