如何在JavaScript中合并两个数组并重复删除项目

时间:2009-10-18 08:34:57

标签: javascript arrays merge

我有两个JavaScript数组:

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

我希望输出为:

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

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

如何在JavaScript中合并两个数组,以便我只按照它们插入原始数组的顺序从每个数组中获取唯一项?

85 个答案:

答案 0 :(得分:1438)

仅合并数组(不删除重复项)

ES5版本使用Array.concat

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

var array3 = array1.concat(array2); // Merges both arrays
// [ 'Vijendra', 'Singh', 'Singh', 'Shakya' ]

ES6版本使用destructuring

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.prototypefor 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;
    }
});

答案 1 :(得分:548)

使用Underscore.js或Lo-Dash,您可以:

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]

http://underscorejs.org/#union

http://lodash.com/docs#union

答案 2 :(得分:228)

首先连接两个数组,然后只过滤掉唯一的项目。

var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b);
var d = c.filter(function (item, pos) {return c.indexOf(item) == pos});

// d is [1,2,3,101,10]

http://jsfiddle.net/simo/98622/

修改

根据@Dmitry的建议(请参阅下面的第二条评论),更明智的解决方案是在与b连接之前过滤a中的唯一项

var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b.filter(function (item) {
    return a.indexOf(item) < 0;
}));

// d is [1,2,3,101,10]

答案 3 :(得分:151)

这是使用spread operator和数组泛型的ECMAScript 6解决方案。

目前它只适用于Firefox,可能还适用于Internet Explorer Technical Preview。

但如果您使用Babel,则可以立即使用。

// Input: [ [1, 2, 3], [101, 2, 1, 10], [2, 1] ]
// Output: [1, 2, 3, 101, 10]
function mergeDedupe(arr)
{
  return [...new Set([].concat(...arr))];
}

答案 4 :(得分:125)

ES6

array1.push(...array2) // => don't remove duplication 

OR

[...array1,...array2] //   =>  don't remove duplication 

OR

[...new Set([...array1 ,...array2])]; //   => remove duplication

答案 5 :(得分:48)

使用Set(ECMAScript 2015),它将如此简单:

const array1 = ["Vijendra", "Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = Array.from(new Set(array1.concat(array2)));

答案 6 :(得分:33)

这是对循环略有不同的看法。通过最新版Chrome中的一些优化,它是解决两个阵列联合的最快方法(Chrome 38.0.2111)。

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

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

var arr = array1.concat(array2),
  len = arr.length;

while (len--) {
  var itm = arr[len];
  if (array3.indexOf(itm) === -1) {
    array3.unshift(itm);
  }
}

while循环:~589k ops / s
过滤器:~445k ops / s
lodash:308k ops / s
for循环:225k ops / s

一条评论指出我的一个设置变量导致我的循环领先于其余部分,因为它没有必要初始化一个空数组来写入。我同意这一点,所以我已经将测试改写为公平竞争,并且包括更快的选择。

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

let whileLoopAlt = function (array1, array2) {
    const array3 = array1.slice(0);
    let len1 = array1.length;
    let len2 = array2.length;
    const assoc = {};

    while (len1--) {
        assoc[array1[len1]] = null;
    }

    while (len2--) {
        let itm = array2[len2];

        if (assoc[itm] === undefined) { // Eliminate the indexOf call
            array3.push(itm);
            assoc[itm] = null;
        }
    }

    return array3;
};

在这个替代解决方案中,我结合了一个答案的关联数组解决方案,以消除循环中的.indexOf()调用,这会使第二个循环减慢很多事情,并包括一些其他用户在其答案中也提出的其他优化措施。

这里的每个值(i-1)上的双循环的最佳答案仍然明显变慢。 lodash仍然很强大,我仍然会推荐给那些不介意在他们的项目中添加库的人。对于那些不想要的人,我的while循环仍然是一个很好的答案,过滤器的答案在这里有很强的表现,在我的测试中击败了最新的Canary Chrome(44.0.2360)

如果您希望提高速度,请查看Mike's answerDan Stocker's answer。在经历了几乎所有可行的答案之后,这些是迄今为止所有结果中最快的。

答案 7 :(得分:31)

您只需使用ECMAScript 6

即可
var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
  • 使用spread operator连接数组。
  • 使用Set创建一组不同的元素。
  • 再次使用spread运算符将Set转换为数组。

答案 8 :(得分:19)

合并两个数组并删除es6中的副本     

let arr1 = [3, 5, 2, 2, 5, 5];
let arr2 = [2, 1, 66, 5];
let unique = [...new Set([...arr1,...arr2])];
console.log(unique);
// [ 3, 5, 2, 1, 66 ]

答案 9 :(得分:16)

Array.prototype.merge = function(/* variable number of arrays */){
    for(var i = 0; i < arguments.length; i++){
        var array = arguments[i];
        for(var j = 0; j < array.length; j++){
            if(this.indexOf(array[j]) === -1) {
                this.push(array[j]);
            }
        }
    }
    return this;
};

更好的阵列合并功能。

答案 10 :(得分:15)

避开嵌套循环(O(n ^ 2))和.indexOf()(+ O(n))。

function merge(a, b) {
    var hash = {}, i;
    for (i=0; i<a.length; i++) {
        hash[a[i]]=true;
    } 
    for (i=0; i<b.length; i++) {
        hash[b[i]]=true;
    } 
    return Object.keys(hash);
}

答案 11 :(得分:14)

只要投入我的两分钱。

function mergeStringArrays(a, b){
    var hash = {};
    var ret = [];

    for(var i=0; i < a.length; i++){
        var e = a[i];
        if (!hash[e]){
            hash[e] = true;
            ret.push(e);
        }
    }

    for(var i=0; i < b.length; i++){
        var e = b[i];
        if (!hash[e]){
            hash[e] = true;
            ret.push(e);
        }
    }

    return ret;
}

这是一个我经常使用的方法,它使用一个对象作为hashlookup表来进行重复检查。假设散列是O(1),那么这在O(n)中运行,其中n是a.length + b.length。老实说,我不知道浏览器如何处理散列,但它在数千个数据点上表现良好。

答案 12 :(得分:14)

基于jsperf,将两个数组合并为一个新数组的最快方法如下:

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%:

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

可接受的答案慢了55%(写的时间更长)

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

答案 13 :(得分:13)

基于ES6的联合解决方案

let arr1 = [1,2,3,4,5];
let arr2 = [3,4,5,6];
let result = [...new Set([...arr1, ...arr2])];
console.log(result);

答案 14 :(得分:13)

为什么不使用对象?看起来你正试图模拟一套。但是,这不会保留订单。

var set1 = {"Vijendra":true, "Singh":true}
var set2 = {"Singh":true,  "Shakya":true}

// Merge second object into first
function merge(set1, set2){
  for (var key in set2){
    if (set2.hasOwnProperty(key))
      set1[key] = set2[key]
  }
  return set1
}

merge(set1, set2)

// Create set from array
function setify(array){
  var result = {}
  for (var item in array){
    if (array.hasOwnProperty(item))
      result[array[item]] = true
  }
  return result
}

答案 15 :(得分:8)

最佳解决方案......

您可以通过点击...

直接在浏览器控制台中查看

没有重复

a = [1, 2, 3];
b = [3, 2, 1, "prince"];

a.concat(b.filter(function(el) {
    return a.indexOf(el) === -1;
}));

重复

["prince", "asish", 5].concat(["ravi", 4])

如果你想要没有重复,你可以从这里尝试更好的解决方案 - Shouting Code

[1, 2, 3].concat([3, 2, 1, "prince"].filter(function(el) {
    return [1, 2, 3].indexOf(el) === -1;
}));

试用Chrome浏览器控制台

 f12 > console

输出:

["prince", "asish", 5, "ravi", 4]

[1, 2, 3, "prince"]

答案 16 :(得分:8)

简化simo's answer并将其转换为一个很好的功能。

function mergeUnique(arr1, arr2){
    return arr1.concat(arr2.filter(function (item) {
        return arr1.indexOf(item) === -1;
    }));
}

答案 17 :(得分:8)

我的一分半便士:

Array.prototype.concat_n_dedupe = function(other_array) {
  return this
    .concat(other_array) // add second
    .reduce(function(uniques, item) { // dedupe all
      if (uniques.indexOf(item) == -1) {
        uniques.push(item);
      }
      return uniques;
    }, []);
};

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

var result = array1.concat_n_dedupe(array2);

console.log(result);

答案 18 :(得分:7)

你可以使用Underscore.js's =&gt;来实现它。的 uniq的

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

console.log(array3)

会打印 [“Vijendra”,“Singh”,“Shakya”]

答案 19 :(得分:6)

//Array.indexOf was introduced in javascript 1.6 (ECMA-262) 
//We need to implement it explicitly for other browsers, 
if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt, from)
  {
    var len = this.length >>> 0;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}
//now, on to the problem

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

var merged = array1.concat(array2);
var t;
for(i = 0; i < merged.length; i++)
  if((t = merged.indexOf(i + 1, merged[i])) != -1)
  {
    merged.splice(t, 1);
    i--;//in case of multiple occurrences
  }

其他浏览器的indexOf方法的实现取自MDC

答案 20 :(得分:6)

可以使用Set。

完成

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

var array3 = array1.concat(array2);
var tempSet = new Set(array3);
array3 = Array.from(tempSet);

//show output
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" > 
  temp text 
</div>

答案 21 :(得分:5)

新解决方案(使用Array.prototype.indexOfArray.prototype.concat):

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;
  };

答案 22 :(得分:5)

array1.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)

关于这个的好处是性能,你通常在使用数组时会链接像filter,map等方法,所以你可以添加那行,它会连接并使用array1重复删除array2而不需要引用到后一个(当你链接你没有的方法时),例如:

someSource()
.reduce(...)
.filter(...)
.map(...) 
// and now you want to concat array2 and deduplicate:
.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)
// and keep chaining stuff
.map(...)
.find(...)
// etc

(我不喜欢污染Array.prototype,这将是尊重链的唯一方式 - 定义一个新函数会打破它 - 所以我觉得这样的事情是唯一的方法来实现)

答案 23 :(得分:5)

对于ES6,只需一行:

a = [1, 2, 3, 4]
b = [4, 5]
[...new Set(a.concat(b))]  // [1, 2, 3, 4, 5]

答案 24 :(得分:5)

Array.prototype.add = function(b){
    var a = this.concat();                // clone current object
    if(!b.push || !b.length) return a;    // if b is not an array, or empty, then return a unchanged
    if(!a.length) return b.concat();      // if original is empty, return b

    // go through all the elements of b
    for(var i = 0; i < b.length; i++){
        // if b's value is not in a, then add it
        if(a.indexOf(b[i]) == -1) a.push(b[i]);
    }
    return a;
}

// Example:
console.log([1,2,3].add([3, 4, 5])); // will output [1, 2, 3, 4, 5]

答案 25 :(得分:4)

  
      
  • 实现这一目标的一种现代方法是简单地使用 spread operator
  •   
  • 为避免重复,我们可以有效地使用 Sets 集合默认情况下不允许重复
  •   
  • 要从Set中获取数组结果,我们可以使用 Array.from()
  •   

所以,这是您的情况的演示-

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var resArr = Array.from(new Set([...array1, ...array2]));
console.log(resArr);

答案 26 :(得分:4)

以下是带有对象数组的对象的选项:

const a = [{param1: "1", param2: 1},{param1: "2", param2: 2},{param1: "4", param2: 4}]
const b = [{param1: "1", param2: 1},{param1: "4", param2: 5}]


var result = a.concat(b.filter(item =>
         !JSON.stringify(a).includes(JSON.stringify(item))
    ));

console.log(result);
//Result [{param1: "1", param2: 1},{param1: "2", param2: 2},{param1: "4", param2: 4},{param1: "4", param2: 5}]

答案 27 :(得分:4)

非常快

使用此discovery,我为中等大小的阵列创建了非常快速的解决方案,并将性能与所选解决方案进行了比较(我将解决方案命名为K)。该解决方案修改输入数组

function K(arr1,arr2) {
  let r=[], h={};
  
  while(arr1.length) {
    let e = arr1.shift();
    if(!h[e]) h[e]=1 && r.push(e);
  }
  
  while(arr2.length) {
    let e = arr2.shift();
    if(!h[e]) h[e]=1 && r.push(e);
  }
  
  return r;
}


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

console.log(K(array1,array2))

性能

今天2020.10.15,我针对选定的解决方案在Chrome v86,Safari v13.1.2和Firefox v81的MacOs HighSierra 10.13.6上进行了测试。

结果

对于所有浏览器

  • 基于where-shift(K)的解决方案最快(除了Safari上的小型阵列,最快的地方)-对于大型阵列,其速度是其他解决方案的1000倍以上(!!!)
  • 对于小型阵列,解决方案F最快(在Safari上最快)
  • 对于小型阵列,解决方案M最慢
  • 对于大型阵列,解决方案E,F,I最慢

我们应该在这里注意,对于Chrome上的大型阵列,K解决方案可能会变慢-详细信息here

enter image description here

详细信息

我执行2个测试用例:

  • 对于2个元素的数组-您可以运行HERE
  • 对于10000个元素数组-您可以运行它HERE

关于解决方案 ABCDEFGHIJ, K(我的), LM 显示在以下片段中

// https://stackoverflow.com/a/10499519/860099
function A(arr1,arr2) {
  return _.union(arr1,arr2)
}

// https://stackoverflow.com/a/53149853/860099
function B(arr1,arr2) {
  return _.unionWith(arr1, arr2, _.isEqual);
}

// https://stackoverflow.com/a/27664971/860099
function C(arr1,arr2) {
  return [...new Set([...arr1,...arr2])]
}

// https://stackoverflow.com/a/48130841/860099
function D(arr1,arr2) {
  return Array.from(new Set(arr1.concat(arr2)))
}

// https://stackoverflow.com/a/23080662/860099
function E(arr1,arr2) {
  return arr1.concat(arr2.filter((item) => arr1.indexOf(item) < 0))
}

// https://stackoverflow.com/a/60421828/860099
function F(array1, array2){
  for (var i = 0; i < array2.length; i++)
    if (array1.indexOf(array2[i]) === -1)
      array1.push(array2[i]);
  return array1;
}

// https://stackoverflow.com/a/28631880/860099
function G(arr1,arr2) {
  var hash = {};
  var i;
  
  for (i = 0; i < arr1.length; i++) {
    hash[arr1[i]] = true;
  }
  for (i = 0; i < arr2.length; i++) {
    hash[arr2[i]] = true;
  }
  return Object.keys(hash);
}

// https://stackoverflow.com/a/13847481/860099
function H(a, b){
    var hash = {};
    var ret = [];

    for(var i=0; i < a.length; i++){
        var e = a[i];
        if (!hash[e]){
            hash[e] = true;
            ret.push(e);
        }
    }

    for(var i=0; i < b.length; i++){
        var e = b[i];
        if (!hash[e]){
            hash[e] = true;
            ret.push(e);
        }
    }

    return ret;
}


// https://stackoverflow.com/a/32108675/860099
function I(a1, a2) {
    var ai = [];
    for (var x = 0; x < a2.length; x++) {
        ai.push(x)
    };

    for (var x = 0; x < a1.length; x++) {
        for (var y = 0; y < ai.length; y++) {
            if (a1[x] === a2[ai[y]]) {
                ai.splice(y, 1);
                y--;
            }
        }
    }

    for (var x = 0; x < ai.length; x++) {
        a1.push(a2[ai[x]]);
    }

    return a1;
}

// https://stackoverflow.com/a/1584377/860099
function J(arr1,arr2) {
  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;
  }

  return arrayUnique(arr1.concat(arr2));
}

// my
function K(arr1,arr2) {
  let r=[], h={};
  
  while(arr1.length) {
    let e = arr1.shift();
    if(!h[e]) h[e]=1 && r.push(e);
  }
  
  while(arr2.length) {
    let e = arr2.shift();
    if(!h[e]) h[e]=1 && r.push(e);
  }
  
  return r;
}

// https://stackoverflow.com/a/25120770/860099
function L(array1, array2) {
    const array3 = array1.slice(0);
    let len1 = array1.length;
    let len2 = array2.length;
    const assoc = {};

    while (len1--) {
        assoc[array1[len1]] = null;
    }

    while (len2--) {
        let itm = array2[len2];

        if (assoc[itm] === undefined) { // Eliminate the indexOf call
            array3.push(itm);
            assoc[itm] = null;
        }
    }

    return array3;
}

// https://stackoverflow.com/a/39336712/860099
function M(arr1,arr2) {
  const comp = f => g => x => f(g(x));
  const apply = f => a => f(a);
  const flip = f => b => a => f(a) (b);
  const concat = xs => y => xs.concat(y);
  const afrom = apply(Array.from);
  const createSet = xs => new Set(xs);
  const filter = f => xs => xs.filter(apply(f));

  const dedupe = comp(afrom) (createSet);

  const union = xs => ys => {
    const zs = createSet(xs);  
    return concat(xs) (
      filter(x => zs.has(x)
       ? false
       : zs.add(x)
    ) (ys));
  }

  return union(dedupe(arr1)) (arr2)
}



// -------------
// TEST
// -------------

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

[A,B,C,D,E,F,G,H,I,J,K,L,M].forEach(f=> {
  console.log(`${f.name} [${f([...array1],[...array2])}]`);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>
  
This shippet only presents functions used in performance tests - it not perform tests itself!

这是针对chrome的示例测试

enter image description here

答案 28 :(得分:4)

有很多用于合并两个数组的解决方案。 它们可以分为两个主要类别(除了使用诸如lodash或underscore.js之类的第三方库之外)。

a)合并两个数组并删除重复的项。

b)在组合项目之前先过滤掉它们。

合并两个数组并删除重复的项目

合并

// mutable operation(array1 is the combined array)
array1.push(...array2);
array1.unshift(...array2);

// immutable operation
const combined = array1.concat(array2);
const combined = [...array1, ...array2];    // ES6

统一

统一数组的方法有很多,我个人建议以下两种方法。

// a little bit tricky
const merged = combined.filter((item, index) => combined.indexOf(item) === index);
const merged = [...new Set(combined)];

在合并项目之前先过滤掉这些项目

还有很多方法,但是由于其简单性,我个人建议以下代码。

const merged = array1.concat(array2.filter(secItem => !array1.includes(secItem)));

答案 29 :(得分:3)

为了它...这是一个单行解决方案:

const x = [...new Set([['C', 'B'],['B', 'A']].reduce( (a, e) => a.concat(e), []))].sort()
// ['A', 'B', 'C']

不是特别易读但可能有助于某人:

  1. 应用reduce函数,并将初始累加器值设置为空数组。
  2. reduce函数使用concat将每个子数组附加到累加器数组上。
  3. 结果作为构造函数参数传递,以创建新的Set
  4. spread运算符用于将Set转换为数组。
  5. sort()函数应用于新数组。

答案 30 :(得分:3)

var arr1 = [1, 3, 5, 6];
var arr2 = [3, 6, 10, 11, 12];
arr1.concat(arr2.filter(ele => !arr1.includes(ele)));
console.log(arr1);

output :- [1, 3, 5, 6, 10, 11, 12]

答案 31 :(得分:2)

看起来接受的答案是我测试中最慢的答案;

注意我正在通过

合并2个对象数组
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<button type='button' onclick='doit()'>do it</button>
<script>
function doit(){
    var items = [];
    var items2 = [];
    var itemskeys = {};
    for(var i = 0; i < 10000; i++){
        items.push({K:i, C:"123"});
        itemskeys[i] = i;
    }

    for(var i = 9000; i < 11000; i++){
        items2.push({K:i, C:"123"});
    }

    console.time('merge');
    var res = items.slice(0);

    //method1();
    method0();
    //method2();

    console.log(res.length);
    console.timeEnd('merge');

    function method0(){
        for(var i = 0; i < items2.length; i++){
            var isok = 1;
            var k = items2[i].K;
            if(itemskeys[k] == null){
                itemskeys[i] = res.length;
                res.push(items2[i]);
            }
        }
    }

    function method1(){
        for(var i = 0; i < items2.length; i++){
            var isok = 1;
            var k = items2[i].K;

            for(var j = 0; j < items.length; j++){
                if(items[j].K == k){
                    isok = 0;
                    break;
                }
            }

            if(isok) res.push(items2[i]);
        }  
    }

    function method2(){
        res = res.concat(items2);
        for(var i = 0; i < res.length; ++i) {
            for(var j = i+1; j < res.length; ++j) {
                if(res[i].K === res[j].K)
                    res.splice(j--, 1);
            }
        }
    }
}
</script>
</body>
</html>

答案 32 :(得分:2)

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

SELECT udf.missingImage(c.images) FROM c

答案 33 :(得分:2)

DeDuplicate单个或Merge和DeDuplicate多个数组输入。以下示例。

使用ES6 - 设置,用于解构

我写了这个简单的函数,它接受多个数组参数。 与上面的解决方案几乎相同,只是有更实际的用例。此函数不会将重复值连接到一个数组中,以便它可以在稍后阶段删除它们。

短功能定义(仅9行)

/**
* This function merging only arrays unique values. It does not merges arrays in to array with duplicate values at any stage.
*
* @params ...args Function accept multiple array input (merges them to single array with no duplicates)
* it also can be used to filter duplicates in single array
*/
function arrayDeDuplicate(...args){
   let set = new Set(); // init Set object (available as of ES6)
   for(let arr of args){ // for of loops through values
      arr.map((value) => { // map adds each value to Set object
         set.add(value); // set.add method adds only unique values
      });
   }
   return [...set]; // destructuring set object back to array object
   // alternativly we culd use:  return Array.from(set);
}

使用示例CODEPEN

// SCENARIO 
let a = [1,2,3,4,5,6];
let b = [4,5,6,7,8,9,10,10,10];
let c = [43,23,1,2,3];
let d = ['a','b','c','d'];
let e = ['b','c','d','e'];

// USEAGE
let uniqueArrayAll = arrayDeDuplicate(a, b, c, d, e);
let uniqueArraySingle = arrayDeDuplicate(b);

// OUTPUT
console.log(uniqueArrayAll); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 43, 23, "a", "b", "c", "d", "e"]
console.log(uniqueArraySingle); // [4, 5, 6, 7, 8, 9, 10]

答案 34 :(得分:2)

执行此操作的最简单方法是使用concat()合并数组,然后使用filter()删除重复项,或使用concat()然后将合并后的数组放入Set()

第一种方式:

const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
//now use filter to remove dups
const removeDuplicates = mergedArray.filter((elem, index) =>  mergedArray.indexOf(elem) === index); // [1,2,3, 4]

第二种方式(但对UI有性能影响):

const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
const removeDuplicates = new Set(mergedArray);

答案 35 :(得分:2)

使用ES2015的功能方法

遵循功能方法,union两个Array只是concatfilter的组合。为了提供最佳性能,我们采用原生的Set数据类型,该类型针对属性查找进行了优化。

无论如何,与union函数结合使用的关键问题是如何处理重复项。以下排列是可能的:

Array A      + Array B

[unique]     + [unique]
[duplicated] + [unique]
[unique]     + [duplicated]
[duplicated] + [duplicated]

前两个排列很容易用一个函数处理。但是,最后两个更复杂,因为只要您依赖Set查找,就无法处理它们。由于切换到普通的旧Object属性查找会导致严重的性能损失,因此以下实现忽略了第三和第四个排列。您必须构建一个单独版本的union来支持它们。

&#13;
&#13;
// small, reusable auxiliary functions

const comp = f => g => x => f(g(x));
const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const afrom = apply(Array.from);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// de-duplication

const dedupe = comp(afrom) (createSet);


// the actual union function

const union = xs => ys => {
  const zs = createSet(xs);  
  return concat(xs) (
    filter(x => zs.has(x)
     ? false
     : zs.add(x)
  ) (ys));
}


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];


// here we go

console.log( "unique/unique", union(dedupe(xs)) (ys) );
console.log( "duplicated/unique", union(xs) (ys) );
&#13;
&#13;
&#13;

从这里开始,实现unionn函数变得微不足道,该函数接受任意数量的数组(受naomik评论的启发):

&#13;
&#13;
// small, reusable auxiliary functions

const uncurry = f => (a, b) => f(a) (b);
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc);

const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// union and unionn

const union = xs => ys => {
  const zs = createSet(xs);  
  return concat(xs) (
    filter(x => zs.has(x)
     ? false
     : zs.add(x)
  ) (ys));
}

const unionn = (head, ...tail) => foldl(union) (head) (tail);


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];
const zs = [0,1,2,3,4,5,6,7,8,9];


// here we go

console.log( unionn(xs, ys, zs) );
&#13;
&#13;
&#13;

结果unionn只是foldl(又名Array.prototype.reduce),它将union作为缩减器。注意:由于实现没有使用额外的累加器,因此在没有参数的情况下应用它时会抛出错误。

答案 36 :(得分:2)

在Dojo 1.6 +

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

dojo.forEach(array3, function(item) {
    if (dojo.indexOf(unique, item) > -1) return;
    unique.push(item); 
});

<强>更新

参见工作代码。

http://jsfiddle.net/UAxJa/1/

答案 37 :(得分:2)

合并无限数量的数组或非数组并使其保持唯一:

function flatMerge() {
    return Array.prototype.reduce.call(arguments, function (result, current) {
        if (!(current instanceof Array)) {
            if (result.indexOf(current) === -1) {
                result.push(current);
            }
        } else {
            current.forEach(function (value) {
                console.log(value);
                if (result.indexOf(value) === -1) {
                    result.push(value);
                }
            });
        }
        return result;
    }, []);
}

flatMerge([1,2,3], 4, 4, [3, 2, 1, 5], [7, 6, 8, 9], 5, [4], 2, [3, 2, 5]);
// [1, 2, 3, 4, 5, 7, 6, 8, 9]

flatMerge([1,2,3], [3, 2, 1, 5], [7, 6, 8, 9]);
// [1, 2, 3, 5, 7, 6, 8, 9]

flatMerge(1, 3, 5, 7);
// [1, 3, 5, 7]

答案 38 :(得分:2)

假设原始数组不需要重复数据删除,这应该非常快,保留原始顺序,并且不会修改原始数组......

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' ]

答案 39 :(得分:2)

我知道这个问题与对象数组无关,但是搜索者的确到了这里。

因此值得将来的读者添加正确的ES6合并方式,然后删除重复项

对象数组

var arr1 = [ {a: 1}, {a: 2}, {a: 3} ];
var arr2 = [ {a: 1}, {a: 2}, {a: 4} ];

var arr3 = arr1.concat(arr2.filter( ({a}) => !arr1.find(f => f.a == a) ));

// [ {a: 1}, {a: 2}, {a: 3}, {a: 4} ]

答案 40 :(得分:1)

var array1 = ["one","two"];
var array2 = ["two", "three"];
var collectionOfTwoArrays = [...array1, ...array2];    
var uniqueList = array => [...new Set(array)];
console.log('Collection :');
console.log(collectionOfTwoArrays);    
console.log('Collection without duplicates :');
console.log(uniqueList(collectionOfTwoArrays));

答案 41 :(得分:1)

减少它们!!!

此替代方案不是显式合并和重复数据消除,而是采用一个数组并用另一个数组进行缩减,以便可以通过累积行为迭代和解构第一个数组的每个值,而通过利用持久性来忽略已经包含的值数组的原因在于递归。

array2.reduce(reducer, array1.reduce(reducer, []))

测试示例:

var array1 = ["Vijendra","Singh","Singh"];
var array2 = ["Singh", "Shakya", "Shakya"];
const reducer = (accumulator, currentValue) => accumulator.includes(currentValue) ? accumulator : [...accumulator, currentValue];

console.log(
  array2.reduce(reducer, array1.reduce(reducer, []))
);

// a reduce on first array is needed to ensure a deduplicated array used as initial value on the second array being reduced

结论

希望避免无聊的for-each方法时更加优雅和有用(不是无用)。

在重复数据删除方面有concat()个限制。

无需像Underscore.js,JQuery或Lo-Dash这样的外部库,也无需创建任何内置函数来实现所需的合并和重复数据删除效果。

哦,嘿!,它可以单线完成!!!


感谢ES5(ECMAScript 2015),漂亮的include()和漂亮的reduce(),使这个答案得以实现。

答案 42 :(得分:1)

如果您不想重复特定属性(例如ID)

let noDuplicate = array1.filter ( i => array2.findIndex(a => i.id==a.id)==-1 );
let result = [...noDuplicate, ...array2];

答案 43 :(得分:1)

构建了一个测试器来检查一些以性能为导向的答案的速度。随意添加更多。到目前为止,Set 是最简单和最快的选项(随着记录数量的增加,幅度更大),至少对于简单的 Number 类型是这样。

const records = 10000, //max records per array
  max_int = 100, //max integer value per array
  dup_rate = .5; //rate of duplication
let perf = {}, //performance logger,
  ts = 0,
  te = 0,
  array1 = [], //init arrays
  array2 = [],
  array1b = [],
  array2b = [],
  a = [];

//populate randomized arrays
for (let i = 0; i < records; i++) {
  let r = Math.random(),
    n = r * max_int;
  if (Math.random() < .5) {
    array1.push(n);
    r < dup_rate && array2.push(n);
  } else {
    array2.push(n);
    r < dup_rate && array1.push(n);
  }
}
//simple deep copies short of rfdc, in case someone wants to test with more complex data types
array1b = JSON.parse(JSON.stringify(array1));
array2b = JSON.parse(JSON.stringify(array2));
console.log('Records in Array 1:', array1.length, array1b.length);
console.log('Records in Array 2:', array2.length, array2b.length);

//test method 1 (jsperf per @Pitouli)
ts = performance.now();
for (let i = 0; i < array2.length; i++)
  if (array1.indexOf(array2[i]) === -1)
    array1.push(array2[i]); //modifies array1
te = performance.now();
perf.m1 = te - ts;
console.log('Method 1 merged', array1.length, 'records in:', perf.m1);
array1 = JSON.parse(JSON.stringify(array1b)); //reset array1

//test method 2 (classic forEach)
ts = performance.now();
array2.forEach(v => array1.includes(v) ? null : array1.push(v)); //modifies array1
te = performance.now();
perf.m2 = te - ts;
console.log('Method 2 merged', array1.length, 'records in:', perf.m2);

//test method 3 (Simplest native option)
ts = performance.now();
a = [...new Set([...array1, ...array2])]; //does not modify source arrays
te = performance.now();
perf.m3 = te - ts;
console.log('Method 3 merged', a.length, 'records in:', perf.m3);

//test method 4 (Selected Answer)
ts = performance.now();
a = array1.concat(array2); //does not modify source arrays
for (let i = 0; i < a.length; ++i) {
  for (let j = i + 1; j < a.length; ++j) {
    if (a[i] === a[j])
      a.splice(j--, 1);
  }
}
te = performance.now();
perf.m4 = te - ts;
console.log('Method 4 merged', a.length, 'records in:', perf.m4);

//test method 5 (@Kamil Kielczewski)
ts = performance.now();

function K(arr1, arr2) {
  let r = [],
    h = {};

  while (arr1.length) {
    let e = arr1.shift(); //modifies array1
    if (!h[e]) h[e] = 1 && r.push(e);
  }

  while (arr2.length) {
    let e = arr2.shift(); //modifies array2
    if (!h[e]) h[e] = 1 && r.push(e);
  }

  return r;
}
a = K(array1, array2);
te = performance.now();
perf.m5 = te - ts;
console.log('Method 5 merged', a.length, 'records in:', perf.m4);
array1 = JSON.parse(JSON.stringify(array1b)); //reset array1
array2 = JSON.parse(JSON.stringify(array2b)); //reset array2


for (let i = 1; i < 6; i++) {
  console.log('Method:', i, 'speed is', (perf['m' + i] / perf.m1 * 100).toFixed(2), '% of Method 1');
}

答案 44 :(得分:1)

就计算时间而言,这是最有效的一个。它还保留了元素的初始顺序。

首先从第二个数组中过滤掉所有重复项,然后将剩下的内容连接到第一个数组。

var a = [1,2,3];
var b = [5,4,3];
var c = a.concat(b.filter(function(i){
    return a.indexOf(i) == -1;
}));
console.log(c); // [1, 2, 3, 5, 4]

这是稍微改进(更快)的版本,有一个缺点,数组不能错过值:

var i, c = a.slice(), ci = c.length;
for(i = 0; i < b.length; i++){
    if(c.indexOf(b[i]) == -1)
        c[ci++] = b[i];
}

答案 45 :(得分:1)

这很简单,可以使用jQuery在一行中完成:

var arr1 = ['Vijendra', 'Singh'], arr2 =['Singh', 'Shakya'];

$.unique(arr1.concat(arr2))//one line

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

答案 46 :(得分:1)

我学会了一种用扩展运算符连接两个数组的小巧方法:

var array1 = ['tom', 'dick', 'harry'];
var array2 = ['martin', 'ricky'];

array1.push(...array2);

&#34; ...&#34; spread运算符将以下数组拆分为单个项,然后push可以将它们作为单独的参数处理。

答案 47 :(得分:1)

如果合并对象数组,请考虑使用lodash UnionBy函数,该函数可用于设置自定义谓词比较对象:

import { unionBy } from 'lodash';

const a = [{a: 1, b: 2}];
const b = [{a: 1, b: 3}];
const c = [{a: 2, b: 4}];

const result = UnionBy(a,b,c, x => x.a);

结果是:[{ a: 1; b: 2 }, { a: 2; b: 4 }]

在结果中使用数组中的第一个传递的匹配

答案 48 :(得分:1)

这是一个简单的例子:

var unique = function(array) {
    var unique = []
    for (var i = 0; i < array.length; i += 1) {
        if (unique.indexOf(array[i]) == -1) {
            unique.push(array[i])
        }
    }
    return unique
}

var uniqueList = unique(["AAPL", "MSFT"].concat(["MSFT", "BBEP", "GE"]));

我们定义unique(array)以删除冗余元素,并使用concat函数组合两个数组。

答案 49 :(得分:1)

这是我的第二个答案,但我相信最快?我希望有人检查我并在评论中回复。

我的第一次尝试达到了大约99k ops / sec,这就是说390k ops / sec与另一个领先的jsperf测试140k(对我而言)。

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

这次尝试尽量减少尽可能多的数组交互,看起来我已经获得了一些性能。

function findMerge(a1, a2) {
    var len1 = a1.length;

    for (var x = 0; x < a2.length; x++) {
        var found = false;

        for (var y = 0; y < len1; y++) {
            if (a2[x] === a1[y]) {
                found = true;
                break;
            }
        }

        if(!found){
            a1.push(a2.splice(x--, 1)[0]);
        }
    }

    return a1;
}

编辑:我对我的功能进行了一些更改,与jsperf网站上的其他人相比,性能更加突出。

答案 50 :(得分:1)

使用Lodash

我发现@ GijsjanB的答案很有用但我的数组包含了许多属性的对象,所以我不得不使用其中一个属性去除它们。

以下是使用myAudioCtx.close();

的解决方案
lodash

作为第三个参数传递的函数有两个参数(两个元素),如果它们相等则必须返回userList1 = [{ id: 1 }, { id: 2 }, { id: 3 }] userList2 = [{ id: 3 }, { id: 4 }, { id: 5 }] // id 3 is repeated in both arrays users = _.unionWith(userList1, userList2, function(a, b){ return a.id == b.id }); // users = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }]

答案 51 :(得分:1)

作为LiraNuna的一部分的一线解决方案:

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

// Merges both arrays
let array3 = array1.concat(array2); 

//REMOVE DUPLICATE
let removeDuplicate = [...new Set(array3)];
console.log(removeDuplicate);

答案 52 :(得分:1)

Array.prototype.union = function (other_array) {
/* you can include a test to check whether other_array really is an array */
  other_array.forEach(function(v) { if(this.indexOf(v) === -1) {this.push(v);}}, this);    
}

答案 53 :(得分:1)

您可以通过Set设置两个输入数组来创建spread

由于集合不允许重复的元素,因此将从两个输入数组中的元素创建union

例如:

var arr1 = ['1', '2', '3']
var arr2 = ['3', '4', '5']

var arr3 = [...new Set([...arr1, ...arr2])]

console.log(arr3);
//(5) ["1", "2", "3", "4", "5"]

答案 54 :(得分:1)

使用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"];

答案 55 :(得分:1)

var MergeArrays=function(arrayOne, arrayTwo, equalityField) {
    var mergeDictionary = {};

    for (var i = 0; i < arrayOne.length; i++) {
        mergeDictionary[arrayOne[i][equalityField]] = arrayOne[i];
    }

    for (var i = 0; i < arrayTwo.length; i++) {
        mergeDictionary[arrayTwo[i][equalityField]] = arrayTwo[i];
    }

    return $.map(mergeDictionary, function (value, key) { return value });
}

利用字典和Jquery,您可以合并两个数组,而不是重复。在我的例子中,我在对象上使用给定的字段,但可能只是对象本身。

答案 56 :(得分:0)

模块化,常规

这可以通过组合两个基本功能来实现。

const getUniqueMerge = (...arrs) => getUniqueArr(mergeArrs(...arrs))
const getUniqueArr = (array) => Array.from(new Set(array))  
const mergeArrs = (...arrs) => [].concat(...arrs)

它可以处理无限个数组或值

console.log(getUniqueMerge(["Vijendra","Singh"],["Singh", "Shakya"])
// ["Vijendra", "Singh", "Shakya"]

console.log(getUniqueMerge(["Sheldon", "Cooper"], ["and", "Cooper", "Amy", "and"], "Farrah", "Amy", "Fowler"))
// ["Sheldon", "Cooper", "and", "Amy", "Farrah", "Fowler"]

答案 57 :(得分:0)

我认为这样工作更快。

removeDup = a => {

None

}

答案 58 :(得分:0)

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,请确保将"lib": ["es2019.array"]添加到tsconfig.json中的编译器选项中。

或...

只需使用lodash _.union

答案 59 :(得分:0)

对于n个数组,您可以像这样获得联合。

Get___

答案 60 :(得分:0)

关心效率,但又想做内联

const s = new Set(array1);
array2.forEach(a => s.add(a));
const merged_array = [...s]; // optional: convert back in array type

答案 61 :(得分:0)

这是另一个使用 Set 的巧妙解决方案:

const o1 = {a: 1};
const arr1 = ['!@#$%^&*()', 'gh', 123, o1, 1, true, undefined, null];
const arr2 = ['!@#$%^&*()', 123, 'abc', o1, 0x001, true, void 0, 0];

const mergeUnique = (...args) => [ ...new Set([].concat(...args)) ];

console.log(mergeUnique(arr1, arr2));

答案 62 :(得分:0)

您可以尝试以下方法:

const union = (a, b) => Array.from(new Set([...a, ...b]));

console.log(union(["neymar","messi"], ["ronaldo","neymar"]));

答案 63 :(得分:0)

   //1.merge two array into one array

   var arr1 = [0, 1, 2, 4];
   var arr2 = [4, 5, 6];

   //for merge array we use "Array.concat"

   let combineArray = arr1.concat(arr2); //output

   alert(combineArray); //now out put is 0,1,2,4,4,5,6 but 4 reapeat

   //2.same thing with "Spread Syntex"

   let spreadArray = [...arr1, ...arr2];

   alert(spreadArray);  //now out put is 0,1,2,4,4,5,6 but 4 reapete


   /*
       if we need remove duplicate element method use are
       1.Using set
       2.using .filter
       3.using .reduce
   */

答案 64 :(得分:0)

如果您仅使用underscore.js,则其中没有unionWith,unionBy

您可以尝试: _.uniq(_.union(arr1, arr2), (obj) => obj.key) (key是每个对象的key参数) 这将有助于在两个数组合并后获得唯一性。

答案 65 :(得分:0)

这是我的解决方案https://gist.github.com/4692150,其中包含深度等于且易于使用的结果:

function merge_arrays(arr1,arr2)
{
   ... 
   return {first:firstPart,common:commonString,second:secondPart,full:finalString}; 
}

console.log(merge_arrays(
[
[1,"10:55"] ,
[2,"10:55"] ,
[3,"10:55"]
],[
[3,"10:55"] ,
[4,"10:55"] ,
[5,"10:55"]
]).second);

result:
[
[4,"10:55"] ,
[5,"10:55"]
]

答案 66 :(得分:0)

之前刚刚写过同样的理由(适用于任意数量的数组):

/**
 * Returns with the union of the given arrays.
 *
 * @param Any amount of arrays to be united.
 * @returns {array} The union array.
 */
function uniteArrays()
{
    var union = [];
    for (var argumentIndex = 0; argumentIndex < arguments.length; argumentIndex++)
    {
        eachArgument = arguments[argumentIndex];
        if (typeof eachArgument !== 'array')
        {
            eachArray = eachArgument;
            for (var index = 0; index < eachArray.length; index++)
            {
                eachValue = eachArray[index];
                if (arrayHasValue(union, eachValue) == false)
                union.push(eachValue);
            }
        }
    }

    return union;
}    

function arrayHasValue(array, value)
{ return array.indexOf(value) != -1; }

答案 67 :(得分: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

答案 68 :(得分: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

答案 69 :(得分:0)

用法:https://gist.github.com/samad-aghaei/7250ffb74ed80732debb1cbb14d2bfb0

var _uniqueMerge = function(opts, _ref){
    for(var key in _ref)
        if (_ref && _ref[key] && _ref[key].constructor && _ref[key].constructor === Object)
          _ref[key] = _uniqueMerge((opts ? opts[key] : null), _ref[key] );
        else if(opts && opts.hasOwnProperty(key))
          _ref[key] = opts[key];
        else _ref[key] = _ref[key][1];
    return _ref;
}

答案 70 :(得分:0)

最好也是最简单的方法是使用函数&#34; some()&#34;返回true或false的JavaScript,指示数组是否包含对象的元素。你可以这样做:

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

var array3 = array1;

array2.forEach(function(elementArray2){
    var isEquals = array1.some(function(elementArray1){
        return elementArray1 === elementArray2;
    })
    if(!isEquals){
        array3.push(elementArray2);
    }
});
console.log(array3);

结果:

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

你希望......没有重复......

答案 71 :(得分:-1)

您可以合并结果并过滤重复项:

let combinedItems = [];

// items is an Array of arrays: [[1,2,3],[1,5,6],...]    
items.forEach(currItems => {
    if (currItems && currItems.length > 0) {
        combinedItems = combinedItems.concat(currItems);
    }
});

let noDuplicateItems = combinedItems.filter((item, index) => {
    return !combinedItems.includes(item, index + 1);
});

答案 72 :(得分:-1)

/**
 * De-duplicate an array keeping only unique values.
 * Use hash table (js object) to filter-out duplicates.
 * The order of array elements is maintained.
 * This algorithm is particularly efficient for large arrays (linear time).
 */
function arrayUniqueFast(arr) {
	var seen = {};
	var result = [];
	var i, len = arr.length;
	for (i = 0; i < len; i++) {
		var item = arr[i];
		// hash table lookup
		if (!seen[item]) {
			result.push(item);
			seen[item] = true;
		}
	}
	return result;
}

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

var result = arrayUniqueFast(array1.concat(array2));
document.write('<br>result: ' + result);

其他方法重复数组,请参阅我的基准:https://jsperf.com/de-duplicate-an-array-keeping-only-unique-values

答案 73 :(得分:-1)

大输入的更好选择是对数组进行排序。然后合并它们。

function sortFunction(a, b) {
        return a - b;
}

arr1.sort(sortFunction);
arr2.sort(sortFunction);

function mergeDedup(arr1, arr2) {

    var i = 0, j = 0, result = [];
    while (i < arr1.length && j < arr2.length) {

        if (arr1[i] < arr2[j]) {
            writeIfNotSameAsBefore(result, arr1[i]);
            i++;
        }
        else if (arr1[i] > arr2[j]) {
            writeIfNotSameAsBefore(result, arr2[j]);
            j++;
        }
        else {
            writeIfNotSameAsBefore(result, arr1[i]);
            i++;
            j++;
        }

    }

    while (i < arr1.length) {
        writeIfNotSameAsBefore(result, arr1[i]);
        i++;
    }

    while (j < arr2.length) {
        writeIfNotSameAsBefore(result, arr2[j]);
        j++;
    }
    return result;
}

function writeIfNotSameAsBefore(arr, item) {
    if (arr[arr.length - 1] !== item) {
        arr[arr.length] = item;
    }
    return arr.length;
}

排序将采用O(nlogn + mlogm),其中n和m是数组的长度,O(x)用于合并,其中x = Max(n,m);

答案 74 :(得分:-1)

给出两个没有重复的简单类型的排序数组,这将在O(n)时间内将它们合并,并且输出也将被排序。

import json

with open('test.json', 'r') as infile:
    json.load(infile) # no problem

答案 75 :(得分:-1)

这很快,整理任意数量的数组,并使用数字和字符串。

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和&#34; 5&#34;,那么

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]);

可能更可取。

答案 76 :(得分:-1)

我在尝试做同样的事情时遇到了这个帖子,但我想尝试不同的东西。我刚刚编写了下面的功能。我还有另一个变量,'compareKeys',(键数组)用于进行浅层对象比较。我将来可能会把它改成一个函数。

无论如何,我没有包含该部分,因为它不适用于该问题。我还将我的代码放入jsperf中。编辑:我在jsperf修复了我的条目。与140k相比,我的功能大约为99k ops / sec。

代码:我首先创建一个可用索引的数组,然后通过迭代第一个数组来消除它们。最后,我通过使用两个数组之间不匹配的修剪下来的索引数组来推进“剩余”。

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

function indiceMerge(a1, a2) {
    var ai = [];
    for (var x = 0; x < a2.length; x++) {
        ai.push(x)
    };

    for (var x = 0; x < a1.length; x++) {
        for (var y = 0; y < ai.length; y++) {
            if (a1[x] === a2[ai[y]]) {
                ai.splice(y, 1);
                y--;
            }
        }
    }

    for (var x = 0; x < ai.length; x++) {
        a1.push(a2[ai[x]]);
    }

    return a1;
}

答案 77 :(得分:-1)

var arr1 = ["neymar","messi"]
var arr2 = ["ronaldo","neymar"]
var arr3 = []
var obj = {}

for(var i = 0 ;i<arr1.length; i+=1){
if(!obj[arr1[i]]){
obj[arr1[i]] = true
arr3.push(arr1[i])
}
}


for(var i = 0 ;i<arr2.length; i+=1){
if(!obj[arr2[i]]){
obj[arr2[i]] = true
arr3.push(arr2[i])
}
}

console.log(arr3)

答案 78 :(得分:-1)

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

我喜欢一个衬里。这会将不同的b元素推送到

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

另一个不会修改

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

答案 79 :(得分:-1)

function set(a, b) {
  return a.concat(b).filter(function(x,i,c) { return c.indexOf(x) == i; });
}

答案 80 :(得分:-1)

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

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"]

答案 81 :(得分:-1)

您可以使用 loadash unionWith -_.unionWith([arrays], [comparator])

此方法类似于_.union,不同之处在于它接受比较器,该比较器被调用以比较数组的元素。从出现该值的第一个数组中选择结果值。比较器由两个参数调用:(arrVal,othVal)。

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
 
var array3 = _.unionWith(array1, array2, _.isEqual);
console.log(array3);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

答案 82 :(得分:-1)

使用:

Array.prototype.merge = function (arr) {
    var key;
    for(key in arr) 
        this[key] = arr[key];
};

答案 83 :(得分:-3)

const merge(...args)=>(new Set([].concat(...args)))

答案 84 :(得分:-4)

取两个数组a和b

var a = ['a','b','c'];

var b = ['d','e','f'];
var c = a.concat(b); 


//c is now an an array with: ['a','b','c','d','e','f']