我有两个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中合并两个数组,以便从每个数组中只获得唯一的项目,其顺序与它们插入原始数组的顺序相同?
当前回答
对于ES6,只有一行:
a = [1, 2, 3, 4]
b = [4, 5]
[...new Set(a.concat(b))] // [1, 2, 3, 4, 5]
其他回答
/***对仅保留唯一值的数组进行重复数据消除。*使用哈希表(js对象)过滤重复项。*保持数组元素的顺序。*该算法对于大型阵列(线性时间)特别有效。*/函数数组UniqueFast(arr){var seen={};var结果=[];变量i,长度=arr.length;对于(i=0;i<len;i++){var项目=arr[i];//哈希表查找if(!seed[item]){result.push(项);seed[项目]=真;}}返回结果;}/////测试var array1=[“Vijendra”,“Singh”];var array2=[“Singh”,“Shakya”];var result=arrayUniqueFast(array1.concat(array2));document.write('<br>result:'+result);
有关阵列重复数据消除的其他方法,请参阅我的基准测试:https://jsperf.com/de-duplicate-an-array-keeping-only-unique-values
编辑:
只有在项目很少的情况下,第一种解决方案才是最快的。当项目超过400项时,Set解决方案将变得最快。当有100000个项目时,它比第一个解决方案快一千倍。
考虑到只有当有很多项时,性能才是重要的,而且Set解决方案是迄今为止最可读的,在大多数情况下,它应该是正确的解决方案
以下性能结果是用少量项目计算的
基于jsperf,将两个数组合并为一个新数组的最快方法(编辑:如果少于400项)如下:
for (var i = 0; i < array2.length; i++)
if (array1.indexOf(array2[i]) === -1)
array1.push(array2[i]);
这个慢17%:
array2.forEach(v => array1.includes(v) ? null : array1.push(v));
这个速度慢45%(编辑:当项目少于100个时。当项目较多时,速度快得多):
var a = [...new Set([...array1 ,...array2])];
而被接受的答案要慢55%(而且写起来要长得多)(编辑:当有10万个项目时,它比任何其他方法都慢几个数量级)
var a = array1.concat(array2);
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);
}
}
https://jsperf.com/merge-2-arrays-without-duplicate
构建一个测试人员来检查一些面向性能的答案的速度。请随意添加更多内容。到目前为止,Set是最简单和最快的选项(随着记录数量的增加,它的边距会更大),至少对于简单的number类型来说是如此。
常量记录=10000,//每个阵列的最大记录数max_int=100,//每个数组的最大整数值dup_rate=.5//复制率让perf={},//性能记录器,ts=0,te=0,array1=[],//初始化数组array2=[],array1b=[],array2b=[],a=[];//填充随机化数组for(设i=0;i<记录;i++){设r=Math.random(),n=r*max_int;如果(Math.random()<.5){array1.push(n);r<dup_rate&&array2.push(n);}其他{阵列2.push(n);r<dup_rate&&array1.push(n);}}//缺少rfdc的简单深度副本,以防有人想要使用更复杂的数据类型进行测试array1b=JSON.parse(JSON.stringify(array1));array2b=JSON.parse(JSON.stringfy(array2));console.log('数组1中的记录:',array1.length,array1b.length);console.log('数组2中的记录:',array2.length,array2b.length);//试验方法1(jsperf per@Pitouli)ts=performance.now();for(设i=0;i<array2.length;i++)如果(array1.indexOf(array2[i])==-1)array1.push(array2[i])//修改数组1te=performance.now();perf.m1=te-ts;console.log('方法1合并',array1.length,'记录在:',perf.m1);array1=JSON.parse(JSON.stringify(array1b))//重置阵列1//测试方法2(经典的Each)ts=performance.now();array2.forEach(v=>array1.includes(v)?null:array1.push(v))//修改数组1te=performance.now();perf.m2=te-ts;console.log('方法2合并',array1.length,'记录在:',perf.m2中);//测试方法3(最简单的本机选项)ts=performance.now();a=[…新集合([…array1,…array2])]//不修改源阵列te=performance.now();perf.m3=te-ts;console.log('方法3合并',a.length,'记录在:',perf.m3);//测试方法4(选定答案)ts=performance.now();a=阵列1.concat(阵列2)//不修改源阵列for(设i=0;i<a.length;++i){for(设j=i+1;j<a.length;++j){如果(a[i]===a[j])a.接头(j-,1);}}te=performance.now();perf.m4=te-ts;console.log('Method 4 merged',a.length,'records in:',perf.m4);//试验方法5(@Kamil Kielczewski)ts=performance.now();函数K(arr1,arr2){设r=[],h={};而(arr1.length){设e=arr1.shift()//修改数组1如果(!h[e])h[e]=1&&r.push(e);}而(arr2.长度){设e=arr2.shift()//修改数组2如果(!h[e])h[e]=1&&r.push(e);}返回r;}a=K(阵列1,阵列2);te=performance.now();perf.m5=te-ts;console.log('Method 5 merged',a.length,'records in:',perf.m4);array1=JSON.parse(JSON.stringify(array1b))//重置阵列1array2=JSON.parse(JSON.stringfy(array2b))//重置阵列2for(设i=1;i<6;i++){console.log('方法:',i,'速度为',(perf[m'+i]/perf.m1*100).toFixed(2),'方法1的%');}
const merge(…args)=>(新集合([].contat(…arg)))
看起来接受的答案是我测试中最慢的;
注意,我正在按Key合并2个对象数组
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<button type='button' onclick='doit()'>do it</button>
<script>
function doit(){
var items = [];
var items2 = [];
var itemskeys = {};
for(var i = 0; i < 10000; i++){
items.push({K:i, C:"123"});
itemskeys[i] = i;
}
for(var i = 9000; i < 11000; i++){
items2.push({K:i, C:"123"});
}
console.time('merge');
var res = items.slice(0);
//method1();
method0();
//method2();
console.log(res.length);
console.timeEnd('merge');
function method0(){
for(var i = 0; i < items2.length; i++){
var isok = 1;
var k = items2[i].K;
if(itemskeys[k] == null){
itemskeys[i] = res.length;
res.push(items2[i]);
}
}
}
function method1(){
for(var i = 0; i < items2.length; i++){
var isok = 1;
var k = items2[i].K;
for(var j = 0; j < items.length; j++){
if(items[j].K == k){
isok = 0;
break;
}
}
if(isok) res.push(items2[i]);
}
}
function method2(){
res = res.concat(items2);
for(var i = 0; i < res.length; ++i) {
for(var j = i+1; j < res.length; ++j) {
if(res[i].K === res[j].K)
res.splice(j--, 1);
}
}
}
}
</script>
</body>
</html>