我有两个JavaScript数组:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
我希望输出为:
var array3 = ["Vijendra","Singh","Shakya"];
输出数组应删除重复的单词。
如何在JavaScript中合并两个数组,以便从每个数组中只获得唯一的项目,其顺序与它们插入原始数组的顺序相同?
我有两个JavaScript数组:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
我希望输出为:
var array3 = ["Vijendra","Singh","Shakya"];
输出数组应删除重复的单词。
如何在JavaScript中合并两个数组,以便从每个数组中只获得唯一的项目,其顺序与它们插入原始数组的顺序相同?
当前回答
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作为其缩减器。注意:由于实现没有使用额外的累加器,所以当您在没有参数的情况下应用它时,它会抛出错误。
其他回答
以下是带有对象数组的对象的选项:
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}]
只是把我的两分钱扔进去。
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;
}
这是我经常使用的方法,它使用一个对象作为哈希查找表来执行重复检查。假设哈希值是O(1),那么这将在O(n)中运行,其中n是a.length+b.length。老实说,我不知道浏览器是如何进行哈希的,但它在数千个数据点上表现良好。
//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
之前写过同样的原因(适用于任意数量的数组):
/**
* 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; }
Use:
Array.prototype.merge = function (arr) {
var key;
for(key in arr)
this[key] = arr[key];
};