我有两个JavaScript数组:

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

我希望输出为:

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

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

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


当前回答

构建一个测试人员来检查一些面向性能的答案的速度。请随意添加更多内容。到目前为止,Set是最简单和最快的选项(随着记录数量的增加,它的边距会更大),至少对于简单的number类型来说是如此。

常量记录=10000,//每个阵列的最大记录数max_int=100,//每个数组的最大整数值dup_rate=.5//复制率让perf={},//性能记录器,ts=0,te=0,array1=[],//初始化数组array2=[],array1b=[],array2b=[],a=[];//填充随机化数组for(设i=0;i<记录;i++){设r=Math.random(),n=r*max_int;如果(Math.random()<.5){array1.push(n);r<dup_rate&&array2.push(n);}其他{阵列2.push(n);r<dup_rate&&array1.push(n);}}//缺少rfdc的简单深度副本,以防有人想要使用更复杂的数据类型进行测试array1b=JSON.parse(JSON.stringify(array1));array2b=JSON.parse(JSON.stringfy(array2));console.log('数组1中的记录:',array1.length,array1b.length);console.log('数组2中的记录:',array2.length,array2b.length);//试验方法1(jsperf per@Pitouli)ts=performance.now();for(设i=0;i<array2.length;i++)如果(array1.indexOf(array2[i])==-1)array1.push(array2[i])//修改数组1te=performance.now();perf.m1=te-ts;console.log('方法1合并',array1.length,'记录在:',perf.m1);array1=JSON.parse(JSON.stringify(array1b))//重置阵列1//测试方法2(经典的Each)ts=performance.now();array2.forEach(v=>array1.includes(v)?null:array1.push(v))//修改数组1te=performance.now();perf.m2=te-ts;console.log('方法2合并',array1.length,'记录在:',perf.m2中);//测试方法3(最简单的本机选项)ts=performance.now();a=[…新集合([…array1,…array2])]//不修改源阵列te=performance.now();perf.m3=te-ts;console.log('方法3合并',a.length,'记录在:',perf.m3);//测试方法4(选定答案)ts=performance.now();a=阵列1.concat(阵列2)//不修改源阵列for(设i=0;i<a.length;++i){for(设j=i+1;j<a.length;++j){如果(a[i]===a[j])a.接头(j-,1);}}te=performance.now();perf.m4=te-ts;console.log('Method 4 merged',a.length,'records in:',perf.m4);//试验方法5(@Kamil Kielczewski)ts=performance.now();函数K(arr1,arr2){设r=[],h={};而(arr1.length){设e=arr1.shift()//修改数组1如果(!h[e])h[e]=1&&r.push(e);}而(arr2.长度){设e=arr2.shift()//修改数组2如果(!h[e])h[e]=1&&r.push(e);}返回r;}a=K(阵列1,阵列2);te=performance.now();perf.m5=te-ts;console.log('Method 5 merged',a.length,'records in:',perf.m4);array1=JSON.parse(JSON.stringify(array1b))//重置阵列1array2=JSON.parse(JSON.stringfy(array2b))//重置阵列2for(设i=1;i<6;i++){console.log('方法:',i,'速度为',(perf[m'+i]/perf.m1*100).toFixed(2),'方法1的%');}

其他回答

可以使用Set完成。

var array1=[“Vijendra”,“Singh”];var array2=[“Singh”,“Shakya”];var array3=array1.concat(array2);var tempSet=新集合(array3);array3=Array.from(tempSet);//显示输出document.body.querySelector(“div”).innerHTML=JSON.stringify(array3);<div style=“width:100%;height:4rem;line height:4rem;background color:steelblue;color:#DDD;text align:center;font-family:Calibri”>临时文本</div>

这是我需要合并(或返回两个数组的并集)时使用的函数。

var union = function (a, b) {
  for (var i = 0; i < b.length; i++)
    if (a.indexOf(b[i]) === -1)
      a.push(b[i]);
  return a;
};

var a = [1, 2, 3, 'a', 'b', 'c'];
var b = [2, 3, 4, 'b', 'c', 'd'];

a = union(a, b);
//> [1, 2, 3, "a", "b", "c", 4, "d"]

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

var array3 = union(array1, array2);
//> ["Vijendra", "Singh", "Shakya"]

新解决方案(使用Array.prototype.indexOf和Array.prototype.cocat):

Array.prototype.uniqueMerge = function( a ) {
    for ( var nonDuplicates = [], i = 0, l = a.length; i<l; ++i ) {
        if ( this.indexOf( a[i] ) === -1 ) {
            nonDuplicates.push( a[i] );
        }
    }
    return this.concat( nonDuplicates )
};

用法:

>>> ['Vijendra', 'Singh'].uniqueMerge(['Singh', 'Shakya'])
["Vijendra", "Singh", "Shakya"]

Array.prototype.indexOf(用于internet explorer):

Array.prototype.indexOf = Array.prototype.indexOf || function(elt)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0) ? Math.ceil(from): Math.floor(from); 
    if (from < 0)from += len;

    for (; from < len; from++)
    {
      if (from in this && this[from] === elt)return from;
    }
    return -1;
  };

只需使用Undercore.js的=>uniq即可实现:

array3 = _.uniq(array1.concat(array2))

console.log(array3)

它将印刷[“Vijendra”、“Singh”、“Shakya”]。

这很快,可以整理任意数量的数组,并且可以处理数字和字符串。

function collate(a){ // Pass an array of arrays to collate into one array
    var h = { n: {}, s: {} };
    for (var i=0; i < a.length; i++) for (var j=0; j < a[i].length; j++)
        (typeof a[i][j] === "number" ? h.n[a[i][j]] = true : h.s[a[i][j]] = true);
    var b = Object.keys(h.n);
    for (var i=0; i< b.length; i++)
        b[i]=Number(b[i]);
    return b.concat(Object.keys(h.s));
}

> a = [ [1,2,3], [3,4,5], [1,5,6], ["spoon", "fork", "5"] ]
> collate( a )

[1, 2, 3, 4, 5, 6, "5", "spoon", "fork"]

如果你不需要区分5和“5”,那么

function collate(a){
    var h = {};
    for (i=0; i < a.length; i++) for (var j=0; j < a[i].length; j++)
        h[a[i][j]] = typeof a[i][j] === "number";
    for (i=0, b=Object.keys(h); i< b.length; i++)
        if (h[b[i]])
            b[i]=Number(b[i]);
    return b;
}
[1, 2, 3, 4, "5", 6, "spoon", "fork"]

可以。

如果你不介意(或者更愿意)所有值都以字符串结尾,那么就这样:

function collate(a){
    var h = {};
    for (var i=0; i < a.length; i++)
        for (var j=0; j < a[i].length; j++)
            h[a[i][j]] = true;
    return Object.keys(h)
}
["1", "2", "3", "4", "5", "6", "spoon", "fork"]

如果您实际上不需要数组,但只想收集唯一值并对其进行迭代,那么(在大多数浏览器(和node.js)中):

h = new Map();
for (i=0; i < a.length; i++)
    for (var j=0; j < a[i].length; j++)
        h.set(a[i][j]);

这可能更好。