简体   繁体   English

如何将两个数组与一个对象合并?

[英]How to merge 2 arrays with objects in one?

I have 2 arrays: 我有2个数组:

  1. [{name:'test', lastname: 'test', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'}]

  2. [{name:'test21', lastname: 'test21', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'},{name:'test22', lastname: 'test22', gender:'m'}]

How to merge these in one array with unique objects (for unique check 'name')? 如何将它们与唯一对象合并为一个数组(对于唯一检查“名称”)?

A combination of filter and find will work filterfind组合将起作用

var a = [{name:'test', lastname: 'test', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'}];

var b = [{name:'test21', lastname: 'test21', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'},{name:'test22', lastname: 'test22', gender:'m'}];

var c = a.filter(a => b.find(b => b.name === a.name) === undefined).concat(b);

console.table(c);

在此处输入图片说明


You could also make a generic uniqueByKey function 您还可以制作一个通用的uniqueByKey函数

var uniqueByKey = (key, xs)=>
  xs.reduce((ys,x)=>
    ys.find(y=> y[key] === x[key]) === undefined
      ? ys.concat([x])
      : ys,
    []);

var a = [{name:'test', lastname: 'test', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'}];

var b = [{name:'test21', lastname: 'test21', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'},{name:'test22', lastname: 'test22', gender:'m'}];

var c = uniqueByKey('name', a.concat(b));

console.table(c);

在此处输入图片说明


If you're dealing with particularly large datasets, using a Set cache instead of Array.prototype.find might be better. 如果要处理特别大的数据集,则最好使用Set缓存而不是Array.prototype.find

var uniqueByKey = (key, xs)=>
  xs.reduce(([set, ys], x)=>
    set.has(x[key])
      ? [set, ys]
      : [set.add(x[key]), ys.concat([x])]
    , [new Set, []]
  ) [1];

var a = [{name:'test', lastname: 'test', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'}];

var b = [{name:'test21', lastname: 'test21', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'},{name:'test22', lastname: 'test22', gender:'m'}];

var c = uniqueByKey('name', a.concat(b));

console.table(c);

在此处输入图片说明

 var arr1 = [{name:'test', lastname: 'test', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'}] var arr2 = [{name:'test', lastname: 'test', gender:'f'},{name:'test21', lastname: 'test21', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'},{name:'test22', lastname: 'test22', gender:'m'}] var newArray =arr1.concat(arr2); var unique = {}; var result = []; newArray.forEach(function (elem) { if (!unique[elem.name]) { result.push(elem); unique[elem.name] = true; } }); console.log(result); document.write(JSON.stringify(result)); 

What you can do to check duplicate elements the fastest method is to add all elements to an object with the name that you want as key, because accessing the keys is very fast: 检查重复元素的最快方法是将所有元素添加到具有您要用作键的名称的对象,因为访问键非常快:

var unified = {},
    unifiedArray = [],
    first = [{name:'test', lastname: 'test', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'}],
    second = [{name:'test21', lastname: 'test21', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'},{name:'test22', lastname: 'test22', gender:'m'}],
    addToUnified = function(obj) {
        if (unified[obj.name]) {
            alert('duplicate detected!\n' + JSON.stringify(obj) + '\n' + ' has same name as\n'  + JSON.stringify(unified[obj.name]));
        } else {
            unifiedArray.push(obj);
            unified[obj.name] = obj;
        }
    }
first.forEach(addToUnified);
second.forEach(addToUnified);

If you just want to get a report you don't need the unifiedArray . 如果您只想获取报告,则不需要unifiedArray If you don't need the report just eliminate the alert 如果您不需要报告,只需消除alert

For a new array, you could use an object as hash table for lookup. 对于新数组,可以将一个对象用作哈希表进行查找。

 var array1 = [{ name: 'test', lastname: 'test', gender: 'f' }, { name: 'test1', lastname: 'test1', gender: 'f' }, { name: 'test2', lastname: 'test2', gender: 'm' }], array2 = [{ name: 'test21', lastname: 'test21', gender: 'f' }, { name: 'test1', lastname: 'test1', gender: 'f' }, { name: 'test2', lastname: 'test2', gender: 'm' }, { name: 'test22', lastname: 'test22', gender: 'm' }], result = function (a1, a2) { function merge(a) { this[a.name] = this[a.name] || r.push(a); } var t = Object.create(null), r = []; a1.forEach(merge, t); a2.forEach(merge, t); return r; }(array1, array2); console.log(result); 

ES6 ES6

 var array1 = [{ name: 'test', lastname: 'test', gender: 'f' }, { name: 'test1', lastname: 'test1', gender: 'f' }, { name: 'test2', lastname: 'test2', gender: 'm' }], array2 = [{ name: 'test21', lastname: 'test21', gender: 'f' }, { name: 'test1', lastname: 'test1', gender: 'f' }, { name: 'test2', lastname: 'test2', gender: 'm' }, { name: 'test22', lastname: 'test22', gender: 'm' }], result = function (a1, a2) { var t = Object.create(null), r = [], m = a => t[a.name] = t[a.name] || r.push(a); a1.forEach(m); a2.forEach(m); return r; }(array1, array2); console.log(result); 

It's easy if you have an Object method like Object.prototype.compare() . 如果您拥有Object.prototype.compare()这样的Object方法,这很容易。 Lets make it. 让它做到。

Object.prototype.compare = function(o){
  var ok = Object.keys(this);
  return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};

Object.prototype.compare() compares two objects for a perfect match of all properties and their values. Object.prototype.compare()比较两个对象以获得所有属性及其值的完美匹配。 So unlike the accepted answer we are not comparing a single property but all of them. 因此,与公认的答案不同,我们不是比较单个属性,而是比较所有属性。 Now it's a simple reducing task. 现在,这是一个简单的还原任务。 Let's see 让我们来看看

 Object.prototype.compare = function(o){ var ok = Object.keys(this); return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false; }; var arr1 = [{name:'test', lastname: 'test', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'}], arr2 = [{name:'test21', lastname: 'test21', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'},{name:'test22', lastname: 'test22', gender:'m'}], united = arr1.reduce((p,c) => p.find(f => f.compare(c)) ? p : p.concat(c),arr2); console.log(JSON.stringify(united)); 

var a = [{name:'test', lastname: 'test', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'}];

var b = [{name:'test21', lastname: 'test21', gender:'f'},{name:'test1', lastname: 'test1', gender:'f'},{name:'test2', lastname: 'test2', gender:'m'},{name:'test22', lastname: 'test22', gender:'m'}];

var c = a.filter(a => b.find(b => b.name === a.name) === undefined).concat(b);

console.table(c);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM