我有两个 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中合并两个数组,以便获取每个数组中唯一的项,并以它们插入原始数组的相同顺序返回?
使用筛选器的最简单解决方案:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var mergedArrayWithoutDuplicates = array1.concat(
array2.filter(seccondArrayItem => !array1.includes(seccondArrayItem))
);
假设原始数组不需要去重,这样做应该非常快,保留原始顺序,并且不修改原始数组...
function arrayMerge(base, addendum){
var out = [].concat(base);
for(var i=0,len=addendum.length;i<len;i++){
if(base.indexOf(addendum[i])<0){
out.push(addendum[i]);
}
}
return out;
}
使用方法:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = arrayMerge(array1, array2);
console.log(array3);
//-> [ 'Vijendra', 'Singh', 'Shakya' ]
看起来在我的测试中被接受的答案是最慢的;
请注意,我正在通过键合并两个对象数组。
<!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>
使用 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
,如果它们相等。
var unique = [];
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1.concat(array2); // Merged both arrays
dojo.forEach(array3, function(item) {
if (dojo.indexOf(unique, item) > -1) return;
unique.push(item);
});
更新
请查看可工作的代码。
以下是关于计算时间最有效的方法,同时保持元素的初始顺序。
首先从第二个数组中筛选出所有重复项,然后将剩余的内容连接到第一个数组中。
var a = [1,2,3];
var b = [5,4,3];
var c = a.concat(b.filter(function(i){
return a.indexOf(i) == -1;
}));
console.log(c); // [1, 2, 3, 5, 4]
这里是略微改进(更快)的版本,但有一个缺点,那就是数组中不能缺少值:
var i, c = a.slice(), ci = c.length;
for(i = 0; i < b.length; i++){
if(c.indexOf(b[i]) == -1)
c[ci++] = b[i];
}
合并任意数量的数组或非数组,并保持唯一性:
function flatMerge() {
return Array.prototype.reduce.call(arguments, function (result, current) {
if (!(current instanceof Array)) {
if (result.indexOf(current) === -1) {
result.push(current);
}
} else {
current.forEach(function (value) {
console.log(value);
if (result.indexOf(value) === -1) {
result.push(value);
}
});
}
return result;
}, []);
}
flatMerge([1,2,3], 4, 4, [3, 2, 1, 5], [7, 6, 8, 9], 5, [4], 2, [3, 2, 5]);
// [1, 2, 3, 4, 5, 7, 6, 8, 9]
flatMerge([1,2,3], [3, 2, 1, 5], [7, 6, 8, 9]);
// [1, 2, 3, 5, 7, 6, 8, 9]
flatMerge(1, 3, 5, 7);
// [1, 3, 5, 7]
_.unionWith([arrays], [comparator])
。这个方法类似于 _.union 方法,但是它接受一个比较器,用于比较数组的元素。结果值是从第一个出现该值的数组中选择的。比较器使用两个参数进行调用:(arrVal, othVal)。
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = _.unionWith(array1, array2, _.isEqual);
console.log(array3);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
这里有另一个使用Set
的巧妙解决方案:
const o1 = {a: 1};
const arr1 = ['!@#$%^&*()', 'gh', 123, o1, 1, true, undefined, null];
const arr2 = ['!@#$%^&*()', 123, 'abc', o1, 0x001, true, void 0, 0];
const mergeUnique = (...args) => [ ...new Set([].concat(...args)) ];
console.log(mergeUnique(arr1, arr2));
关注效率,但希望在行内完成
const s = new Set(array1);
array2.forEach(a => s.add(a));
const merged_array = [...s]; // optional: convert back in array type
b
到a
) :a=a.concat(b);
从数组a
中删除重复项 (就地操作) :a=a.filter((i,p)=>a.indexOf(i)===p);
- ashleedawg