我有两个JavaScript数组:

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

我希望输出为:

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

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

如何在JavaScript中合并两个数组,以便从每个数组中只获得唯一的项目,其顺序与它们插入原始数组的顺序相同?


当前回答

使用reduce func查看的另一种方法:

function mergeDistinct(arResult, candidate){
  if (-1 == arResult.indexOf(candidate)) {
    arResult.push(candidate);
  }
  return arResult;
}

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

var arMerge = [];
arMerge = array1.reduce(mergeDistinct, arMerge);
arMerge = array2.reduce(mergeDistinct, arMerge);//["Vijendra","Singh","Shakya"];

其他回答

编辑:

只有在项目很少的情况下,第一种解决方案才是最快的。当项目超过400项时,Set解决方案将变得最快。当有100000个项目时,它比第一个解决方案快一千倍。

考虑到只有当有很多项时,性能才是重要的,而且Set解决方案是迄今为止最可读的,在大多数情况下,它应该是正确的解决方案

以下性能结果是用少量项目计算的


基于jsperf,将两个数组合并为一个新数组的最快方法(编辑:如果少于400项)如下:

for (var i = 0; i < array2.length; i++)
    if (array1.indexOf(array2[i]) === -1)
      array1.push(array2[i]);

这个慢17%:

array2.forEach(v => array1.includes(v) ? null : array1.push(v));

这个速度慢45%(编辑:当项目少于100个时。当项目较多时,速度快得多):

var a = [...new Set([...array1 ,...array2])];

而被接受的答案要慢55%(而且写起来要长得多)(编辑:当有10万个项目时,它比任何其他方法都慢几个数量级)

var a = array1.concat(array2);
for (var i = 0; i < a.length; ++i) {
    for (var j = i + 1; j < a.length; ++j) {
        if (a[i] === a[j])
            a.splice(j--, 1);
    }
}

https://jsperf.com/merge-2-arrays-without-duplicate

假设原始阵列不需要重复数据消除,这应该非常快,保持原始顺序,并且不会修改原始阵列。。。

function arrayMerge(base, addendum){
    var out = [].concat(base);
    for(var i=0,len=addendum.length;i<len;i++){
        if(base.indexOf(addendum[i])<0){
            out.push(addendum[i]);
        }
    }
    return out;
}

用法:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = arrayMerge(array1, array2);

console.log(array3);
//-> [ 'Vijendra', 'Singh', 'Shakya' ]

ES6提供了一种单线解决方案,通过使用析构函数和集合来合并多个数组而不重复。

const array1 = ['a','b','c'];
const array2 = ['c','c','d','e'];
const array3 = [...new Set([...array1,...array2])];
console.log(array3); // ["a", "b", "c", "d", "e"]

仅合并阵列(不删除重复项)

ES5版本使用Array.concat:

var array1=[“Vijendra”,“Singh”];var array2=[“Singh”,“Shakya”];array1=array1.concat(array2);console.log(array1);

ES6版本使用销毁

const array1 = ["Vijendra","Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = [...array1, ...array2];

由于没有“内置”的方法来删除重复项(ECMA-262实际上有Array.forEach,这将非常好),因此我们必须手动执行:

Array.prototype.unique = function() {
    var a = this.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
};

然后,要使用它:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
// Merges both arrays and gets unique items
var array3 = array1.concat(array2).unique(); 

这也将保持阵列的顺序(即,不需要排序)。

由于许多人对Array.prototype的原型扩充和in循环感到恼火,这里有一种不太侵入性的方法来使用它:

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(a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
}

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
    // Merges both arrays and gets unique items
var array3 = arrayUnique(array1.concat(array2));

对于那些有幸使用ES5可用的浏览器的人,可以像这样使用Object.defineProperty:

Object.defineProperty(Array.prototype, 'unique', {
    enumerable: false,
    configurable: false,
    writable: false,
    value: function() {
        var a = this.concat();
        for(var i=0; i<a.length; ++i) {
            for(var j=i+1; j<a.length; ++j) {
                if(a[i] === a[j])
                    a.splice(j--, 1);
            }
        }

        return a;
    }
});

带过滤器的最简单解决方案:

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

var mergedArrayWithoutDuplicates = array1.concat(
  array2.filter(seccondArrayItem => !array1.includes(seccondArrayItem))
);