我有两个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中合并两个数组,以便从每个数组中只获得唯一的项目,其顺序与它们插入原始数组的顺序相同?
当前回答
这是一个使用扩展运算符和数组泛型的ECMAScript 6解决方案。
目前,它只适用于Firefox,也可能适用于Internet Explorer技术预览版。
但如果你使用巴别尔,你现在就可以拥有它。
常量输入=[[1, 2, 3],[101, 2, 1, 10],[2, 1]];常量合并重复数据消除=(arr)=>{return[…new Set([].contat(…arr))];}console.log(“输出”,合并重复数据消除(输入));
其他回答
模块化,通用
这可以通过组成两个基本功能来实现。
const getUniqueMerge = (...arrs) => getUniqueArr(mergeArrs(...arrs))
const getUniqueArr = (array) => Array.from(new Set(array))
const mergeArrs = (...arrs) => [].concat(...arrs)
它可以处理无限的数组或值
console.log(getUniqueMerge(["Vijendra","Singh"],["Singh", "Shakya"])
// ["Vijendra", "Singh", "Shakya"]
console.log(getUniqueMerge(["Sheldon", "Cooper"], ["and", "Cooper", "Amy", "and"], "Farrah", "Amy", "Fowler"))
// ["Sheldon", "Cooper", "and", "Amy", "Farrah", "Fowler"]
使用Undercore.js或Lo Dash,您可以执行以下操作:
console.log(_.union([1,2,3],[101,2,1,10],[2,1]));<script src=“https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js“></script>
http://underscorejs.org/#union
http://lodash.com/docs#union
仅合并阵列(不删除重复项)
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;
}
});
新解决方案(使用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;
};
这里有一个稍微不同的循环。通过Chrome最新版本中的一些优化,它是解决两个数组联合的最快方法(Chrome 38.0.2111)。
http://jsperf.com/merge-two-arrays-keeping-only-unique-values
var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [];
var arr = array1.concat(array2),
len = arr.length;
while (len--) {
var itm = arr[len];
if (array3.indexOf(itm) === -1) {
array3.unshift(itm);
}
}
while循环:约589k ops/s滤波器:~44k ops/slodash:30.8万次/秒对于循环:225k操作/秒
一条评论指出,我的一个设置变量导致我的循环领先于其他循环,因为它不需要初始化一个空数组来写入。我同意这一点,所以我已经将测试重写为公平的环境,并包含了一个更快的选项。
http://jsperf.com/merge-two-arrays-keeping-only-unique-values/52
let whileLoopAlt = function (array1, array2) {
const array3 = array1.slice(0);
let len1 = array1.length;
let len2 = array2.length;
const assoc = {};
while (len1--) {
assoc[array1[len1]] = null;
}
while (len2--) {
let itm = array2[len2];
if (assoc[itm] === undefined) { // Eliminate the indexOf call
array3.push(itm);
assoc[itm] = null;
}
}
return array3;
};
在另一种解决方案中,我结合了一个答案的关联数组解决方案,以消除循环中的.indexOf()调用,该调用通过第二个循环大大降低了速度,并包含了其他用户在其答案中建议的一些其他优化。
这里的最高答案是每个值(i-1)都有一个双循环,但速度仍然很慢。lodash仍然做得很好,我仍然会向任何不介意在项目中添加库的人推荐它。对于那些不想这样做的人来说,我的while循环仍然是一个很好的答案,过滤器的答案在这里表现得很好,在我的测试中击败了最新的Canary Chrome(44.0.2360)。
如果你想加快速度,看看迈克和丹·斯托克的答案。在经历了几乎所有可行的答案之后,这些是迄今为止所有结果中最快的。