我有两个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中合并两个数组,以便从每个数组中只获得唯一的项目,其顺序与它们插入原始数组的顺序相同?
当前回答
最简单的方法是使用concat()合并数组,然后使用filter()删除重复项,或者使用concat()将合并的数组放入Set()中。
第一种方式:
const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
//now use filter to remove dups
const removeDuplicates = mergedArray.filter((elem, index) => mergedArray.indexOf(elem) === index); // [1,2,3, 4]
第二种方式(但对UI有性能影响):
const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
const removeDuplicates = new Set(mergedArray);
其他回答
之前写过同样的原因(适用于任意数量的数组):
/**
* 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; }
以下是带有对象数组的对象的选项:
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}]
表演
今天2020.10.15我在Chrome v86、Safari v13.1.2和Firefox v81上对MacOs HighSierra 10.13.6进行了测试,以确定所选的解决方案。
后果
适用于所有浏览器
解决方案H快速/最快解决方案L很快解决方案D在大型阵列的chrome上速度最快解决方案G在小阵列上速度很快解决方案M对于小型阵列来说是最慢的解决方案E对于大型阵列来说是最慢的
细节
我执行两个测试用例:
对于2元素数组-您可以在此处运行对于10000个元素数组-您可以在这里运行
关于解决方案A.BCDEGHJLM在下面的片段中显示
// https://stackoverflow.com/a/10499519/860099函数A(arr1,arr2){返回_并集(arr1,arr2)}// https://stackoverflow.com/a/53149853/860099函数B(arr1,arr2){return _.unionWith(arr1,arr2,_.isEqual);}// https://stackoverflow.com/a/27664971/860099函数C(arr1,arr2){return[…new Set([…arr1,…arr2])]}// https://stackoverflow.com/a/48130841/860099函数D(arr1,arr2){return Array.from(新集合(arr1.concat(arr2)))}// https://stackoverflow.com/a/23080662/860099函数E(arr1,arr2){return arr1.concat(arr2.filter((项)=>arr1.indexOf(项)<0))}// https://stackoverflow.com/a/28631880/860099函数G(arr1,arr2){var哈希={};变量i;对于(i=0;i<arr1.length;i++){hash[arr1[i]=真;}对于(i=0;i<arr2.length;i++){hash[ar2[i]=真;}return Object.keys(哈希);}// https://stackoverflow.com/a/13847481/860099函数H(a,b){var哈希={};var ret=[];对于(var i=0;i<a.length;i++){变量e=a[i];if(!hash[e]){hash[e]=真;ret.push(e);}}对于(var i=0;i<b.length;i++){变量e=b[i];if(!hash[e]){hash[e]=真;ret.push(e);}}返回ret;}// https://stackoverflow.com/a/1584377/860099函数J(arr1,arr2){函数arrayUnique(数组){var a=array.contat();对于(var i=0;i<a.length;++i){对于(var j=i+1;j<a.length;++j){如果(a[i]===a[j])a.接头(j-,1);}}返回a;}return arrayUnique(arr1.concat(arr2));}// https://stackoverflow.com/a/25120770/860099函数L(array1,array2){常量数组3=数组1.slice(0);设len1=阵列长度;设len2=阵列2.length;常量assoc={};而(len1--){assoc[array1[len1]]=空;}而(len2--){设itm=array2[len2];if(assoc[itm]==未定义){//消除indexOf调用array3.push(itm);assoc[itm]=空;}}返回数组3;}// https://stackoverflow.com/a/39336712/860099函数M(arr1,arr2){常量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));}返回联合(重复数据消除(arr1))(arr2)}// -------------//测试// -------------var array1=[“Vijendra”,“Singh”];var array2=[“Singh”,“Shakya”];[A、B、C、D、E、G、H、J、L、M]。对于每个(f=>{console.log(`${f.name}[${f([…array1],[…array2])}]`);})<script src=“https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js“integrity=”sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==“crossrorigin=”匿名“></script>此代码段仅显示性能测试中使用的函数-它本身不执行测试!
下面是chrome的示例测试运行
更新
我删除了案例F、I、K,因为它们修改了输入数组,基准测试给出了错误的结果
如果要检查唯一对象,请在比较中使用JSON.stringify。
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(JSON.stringify(a[i]) === JSON.stringify(a[j]))
a.splice(j--, 1);
}
}
return a;
}
使用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。