我有两个JavaScript数组:

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

我希望输出为:

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

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

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


当前回答

这里是关于计算时间方面最有效的方法。它还保持元素的初始顺序。

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

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

其他回答

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

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]

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

function merge(a, b) {
    let i=0;
    let j=0;
    let c = [];
    for (;;) {
        if (i == a.length) {
            if (j == b.length) return c;
            c.push(b[j++]);
        } else if (j == b.length || a[i] < b[j]) {
            c.push(a[i++]);
        } else {
            if (a[i] == b[j]) ++i;   // skip duplicates
            c.push(b[j++]);
        }
    }
}

我有一个类似的请求,但它具有数组中元素的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"]
Array.prototype.pushUnique = function(values)
{
    for (var i=0; i < values.length; i++)
        if (this.indexOf(values[i]) == -1)
            this.push(values[i]);
};

Try:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
array1.pushUnique(array2);
alert(array1.toString());  // Output: 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]);

这可能更好。