我有两个JavaScript数组:

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

我希望输出为:

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

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

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


当前回答

为此……这里有一个单行解决方案:

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

不是特别可读,但它可能会帮助某人:

将初始累加器值设置为空数组的reduce函数应用于空数组。reduce函数使用concat将每个子数组附加到累加器数组上。其结果作为构造函数参数传递,以创建新的Set。排列运算符用于将集合转换为数组。sort()函数应用于新数组。

其他回答

Use:

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

在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/

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

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

ES2015的功能方法

按照函数方法,两个数组的联合只是concat和filter的组合。为了提供最佳性能,我们使用本机Set数据类型,该类型针对属性查找进行了优化。

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

Array A      + Array B

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

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


//小型、可重复使用的辅助功能常量comp=f=>g=>x=>f(g(x));常量应用=f=>a=>f(a);常量flip=f=>b=>a=>f(a)(b);常量concat=xs=>y=>xs.contat(y);const afrom=应用(Array.from);const createSet=xs=>新集合(xs);常量过滤器=f=>xs=>xs.filter(apply(f));//重复数据消除常量重复数据删除=comp(afrom)(createSet);//实际联合函数常量并集=xs=>ys=>{const zs=创建集(xs);返回凹面(xs)(滤波器(x=>zs.has(x)? 假的:zs.add(x))(ys));}//模拟数据常量xs=[1,2,2,3,4,5];常量=[0,1,2,3,3,4,5,6,6];//我们来了console.log(“unique/unique”,union(重复数据消除(xs))(ys));console.log(“重复/唯一”,union(xs)(ys));

从这里开始,实现unionn函数变得很简单,它接受任意数量的数组(灵感来自naomik的评论):

//小型、可重复使用的辅助功能常量未修正=f=>(a,b)=>f(a)(b);常量foldl=f=>acc=>xs=>xs.reduce(uncurry(f),acc);常量应用=f=>a=>f(a);常量flip=f=>b=>a=>f(a)(b);常量concat=xs=>y=>xs.contat(y);const createSet=xs=>新集合(xs);常量过滤器=f=>xs=>xs.filter(apply(f));//工会和工会常量并集=xs=>ys=>{const zs=创建集(xs);返回凹面(xs)(滤波器(x=>zs.has(x)? 假的:zs.add(x))(ys));}常量unionn=(头,…尾)=>foldl(联合)(头)(尾);//模拟数据常量xs=[1,2,2,3,4,5];常量=[0,1,2,3,3,4,5,6,6];常数zs=[0,1,2,3,4,5,6,7,8,9];//我们来了console.log(unionn(xs,ys,zs));

事实证明unionn只是foldl(又名Array.protocol.reduce),它将union作为其缩减器。注意:由于实现没有使用额外的累加器,所以当您在没有参数的情况下应用它时,它会抛出错误。

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

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

array1.push(...array2);

“…”扩展运算符将以下数组拆分为单个项,然后push可以将它们作为单独的参数处理。