如何在JavaScript中合并两个数组并去重

1962

我有两个 JavaScript 数组:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

我希望输出结果是:

var array3 = ["Vijendra","Singh","Shakya"];

输出数组应该删除重复的单词。

我如何在JavaScript中合并两个数组,以便获取每个数组中唯一的项,并以它们插入原始数组的相同顺序返回?


32
在发布新答案之前,请考虑此问题已经有75个以上的答案。请确保您的答案提供的信息不在现有答案中。 - janniks
5
结果为 [1, 2, 3, 4],这行代码使用了 ES6 的 Set 数据结构和展开运算符将两个数组去重合并。 - Denis Giffeler
如果您想要一个更通用的解决方案,也包括深度合并,请查看这个问题。一些答案也涵盖了数组。 - Martin Braun
简而言之 - 合并数组 (ba) : a=a.concat(b); 从数组 a 中删除重复项 (就地操作) : a=a.filter((i,p)=>a.indexOf(i)===p); - ashleedawg
如果你不想再有更多答案,可以关闭问题。 - Janos Vinceller
问题仍然开放,等待不同、创新、前沿的答案。这也是免责声明的原因。 - Rodrigo Rodrigues
92个回答

1
对于n个数组,可以这样获取它们的并集。
function union(arrays) {
    return new Set(arrays.flat()).keys();
};

几乎,但不完全:Set.keys()(是 Set.values() 的“别名”)返回一个set iterator,它不是一个数组,正如所要求的那样。 - undefined

1

ES2019

您可以像这样使用它:union(array1, array2, array3, ...)

/**
 * Merges two or more arrays keeping unique items. This method does
 * not change the existing arrays, but instead returns a new array.
 */
function union<T>(...arrays: T[]) {
  return [...new Set([...arrays].flat())];
}

因为flat()函数,所以这是ES2019,但您可以使用core-js作为polyfill。这里的T是TypeScript泛型类型,如果您不使用TypeScript,则可以删除它。如果您正在使用TypeScript,请确保在tsconfig.json的编译器选项中添加"lib": ["es2019.array"]
或者... 只需使用lodash _.union

关于 union<T>(...arrays: T[]) - 这是 JavaScript/ES2019 吗? - undefined
@Abdull 不是,但 flat() 是。请阅读帖子中的描述。 - undefined

1
如果您想检查唯一的对象,则在比较中使用JSON.stringify。
function arrayUnique(array) {
    var a = array.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(JSON.stringify(a[i]) === JSON.stringify(a[j]))
                a.splice(j--, 1);
        }
    }

    return a;
}

0

如果你像我一样需要支持旧版浏览器,这个代码可以在IE6+上运行。

function es3Merge(a, b) {
    var hash = {},
        i = (a = a.slice(0)).length,
        e;

    while (i--) {
        hash[a[i]] = 1;
    }

    for (i = 0; i < b.length; i++) {
        hash[e = b[i]] || a.push(e);
    }

    return a;
};

http://jsperf.com/merge-two-arrays-keeping-only-unique-values/22


0
Array.prototype.pushUnique = function(values)
{
    for (var i=0; i < values.length; i++)
        if (this.indexOf(values[i]) == -1)
            this.push(values[i]);
};

尝试:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
array1.pushUnique(array2);
alert(array1.toString());  // Output: Vijendra,Singh,Shakya

0
var a = [1,2,3]
var b = [1,2,4,5]

我喜欢一行代码。这将把不同的b元素推到a中。

b.forEach(item => a.includes(item) ? null : a.push(item));

另外一种版本,不会修改a

var c = a.slice();
b.forEach(item => c.includes(item) ? null : c.push(item));

0

我有一个类似的请求,但它是关于数组中元素的Id

这里是我进行去重的方法。

它简单易懂,易于维护,使用效果也很好。

// Vijendra's Id = Id_0
// Singh's Id = Id_1
// Shakya's Id = Id_2

let item0 = { 'Id': 'Id_0', 'value': 'Vijendra' };
let item1 = { 'Id': 'Id_1', 'value': 'Singh' };
let item2 = { 'Id': 'Id_2', 'value': 'Shakya' };

let array = [];

array = [ item0, item1, item1, item2 ];

let obj = {};
array.forEach(item => {
    obj[item.Id] = item;
});

let deduplicatedArray = [];
let deduplicatedArrayOnlyValues = [];
for(let [index, item] of Object.values(obj).entries()){
    deduplicatedArray = [ ...deduplicatedArray, item ];
    deduplicatedArrayOnlyValues = [ ...deduplicatedArrayOnlyValues , item.value ];
};
    
console.log( JSON.stringify(array) );
console.log( JSON.stringify(deduplicatedArray) );
console.log( JSON.stringify(deduplicatedArrayOnlyValues ) );

控制台日志

[{"recordId":"Id_0","value":"Vijendra"},{"recordId":"Id_1","value":"Singh"},{"recordId":"Id_1","value":"Singh"},{"recordId":"Id_2","value":"Shakya"}]

[{"recordId":"Id_0","value":"Vijendra"},{"recordId":"Id_1","value":"Singh"},{"recordId":"Id_2","value":"Shakya"}]

["Vijendra","Singh","Shakya"]

0

如果您有非常大的列表,这种方法并不高效,而且这并不适用于合并,因为已经有许多解决方案被记录下来了。但是我通过这个解决方案解决了我的问题(因为大多数数组过滤的解决方案都适用于简单的数组)。

const uniqueVehiclesServiced = 
  invoice.services.sort().filter(function(item, pos, ary) {
    const firstIndex = invoice.services.findIndex((el, i, arr) => el.product.vin === item.product.vin)

  return !pos || firstIndex == pos;
});

0

我认为这个更快。

removeDup = a => {

    for (let i = a.length - 1; i >= 0; i--) {
        for (let j = i-1; j >= 0; j--) {
            if (a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
}

0
使用Array.prototype.flat()

const input = [
  [1, 2, 3, 1],
  [101, 2, 1, 10],
  [2, 1]
];

const union = (arr) => {
  return [  ...new Set( arr.flat() )  ];
}

console.log('output', union(input));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接