我有两个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中合并两个数组,以便从每个数组中只获得唯一的项目,其顺序与它们插入原始数组的顺序相同?
当前回答
对于大型输入,更好的选择是对数组进行排序。然后合并它们。
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);
其他回答
使用Lodash
我发现@GijsjanB的答案很有用,但我的数组包含具有许多属性的对象,因此我不得不使用其中一个属性来消除它们的重复。
这是我使用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 }]
作为第三个参数传递的函数有两个参数(两个元素),如果它们相等,则必须返回true。
仅合并阵列(不删除重复项)
ES5版本使用Array.concat:
var array1=[“Vijendra”,“Singh”];var array2=[“Singh”,“Shakya”];array1=array1.concat(array2);console.log(array1);
ES6版本使用销毁
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.prototype的原型扩充和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;
}
});
function set(a, b) {
return a.concat(b).filter(function(x,i,c) { return c.indexOf(x) == i; });
}
这很简单,可以用jQuery在一行中完成:
var arr1 = ['Vijendra', 'Singh'], arr2 =['Singh', 'Shakya'];
$.unique(arr1.concat(arr2))//one line
["Vijendra", "Singh", "Shakya"]
//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