我有两个JavaScript数组:

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

我希望输出为:

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

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

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


当前回答

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,您可以合并这两个数组,而不会得到重复项。在我的示例中,我在对象上使用给定的字段,但可能只是对象本身。

其他回答

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,这将是尊重链的唯一方式——定义一个新函数将打破它——所以我认为这样做是实现这一点的唯一方式)

新解决方案(使用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;
  };

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

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

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

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

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

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]

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

无论如何,我没有包括那部分,因为它不适用于这个问题。我还将代码放入jsperf中。编辑:我修复了jsperf中的条目。与140k相比,我的函数的运算速度约为99k次/秒。

对于代码:我首先创建一个可用索引数组,然后通过迭代第一个数组来消除它们。最后,我通过使用两个数组之间不匹配的缩减索引数组来插入“剩余部分”。

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