我有两个 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中合并两个数组,以便获取每个数组中唯一的项,并以它们插入原始数组的相同顺序返回?
仅合并数组(不移除重复项)
Array.concat
:var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
array1 = array1.concat(array2);
console.log(array1);
原始答案是多年前的。ES6已完全支持,IE终于退出历史舞台。以下是合并基本数组和对象数组的最简单方法:
const merge = (a, b, predicate = (a, b) => a === b) => {
const c = [...a]; // copy to avoid side effects
// add all items from B to copy C if they're not already present
b.forEach((bItem) => (c.some((cItem) => predicate(bItem, cItem)) ? null : c.push(bItem)))
return c;
}
merge(['a', 'b', 'c'], ['c', 'x', 'd']);
// => ['a', 'b', 'c', 'x', 'd']
merge([{id: 1}, {id: 2}], [{id: 2}, {id: 3}], (a, b) => a.id === b.id);
// [{id: 1}, {id: 2}, {id: 3}]
const array1 = ["Vijendra","Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = [...array1, ...array2];
Array.forEach
,这对此操作非常好),我们必须手动完成。请注意,这会污染Array
原型,请谨慎使用。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
的原型扩展和for 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));
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;
}
});
[a, b, c]
和 [x, b, d]
是两个数组(请用引号表示),则它们的合并结果为 [a, b, c, x, b, d]
。使用 unique()
函数后,输出结果为 [a, c, x, b, d]
,但是我认为这并不能保持原有顺序,我相信 OP 想要的输出结果应该是 [a, b, c, x, d]
。 - AmarghoshhasOwnProperty
时,应该始终与 for ... in
一起使用,此时原型方法是可以的。 - mulllhausenSet()
即可。 - cmcculloh通过使用 Underscore.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>
underscore.flatten()
,它比union
更好,因为它可以接受一个数组对象作为参数。 - weaver[...array1,...array2] // => don't remove duplication
或者
[...new Set([...array1 ,...array2])]; // => remove duplication
union
+ 第一个示例对于大型Array
会导致堆栈溢出 + 第三个示例非常缓慢并且消耗大量内存,因为必须构建两个中间的Array
+ 第三个示例只能用于在编译时已知数量的Array
的union
。 - user6445533首先将这两个数组连接起来,然后只筛选出唯一的项:
var a = [1, 2, 3], b = [101, 2, 1, 10]
var c = a.concat(b)
var d = c.filter((item, pos) => c.indexOf(item) === pos)
console.log(d) // d is [1, 2, 3, 101, 10]
如建议的那样,更有效率的解决方案是在将 a
与 b
连接之前过滤掉 b
中的唯一项:
var a = [1, 2, 3], b = [101, 2, 1, 10]
var c = a.concat(b.filter((item) => a.indexOf(item) < 0))
console.log(c) // c is [1, 2, 3, 101, 10]
var c = [...a, ...b.filter(o => !~a.indexOf(o))];
2. var c = [...new Set([...a, ...b])];
☺ - 7vujy0f0hylet a = [{id: 1, name:"sam", id:2, name: "roy" }]; let b = [{id: 1, name:"sam", id:3, name: "john" }]
输出应该是 [{id: 1, name:"sam", id:2, name: "roy" , id:3, name: "john"}]
。 - AbhimanuSharmaArray.from
代替展开运算符:Array.from(new Set([].concat(...arr)))
- Henry Blythreturn [...new Set(arr)];
而不是 return [...new Set([].concat(...arr))];
?并不是说这样做是错误的,只是想知道为什么你要这样做。 - user210757const array1 = ["Vijendra", "Singh"];
const array2 = ["Singh", "Shakya"];
console.log(Array.from(new Set(array1.concat(array2))));
const array3 = [...new Set(array1.concat(array2))]
意思是将 array1
和 array2
合并成一个数组,并去除其中的重复元素,然后将结果赋值给 array3
。 - Robby CornelissenArray.from(new Set(array1.concat(array2)))
。这将合并两个数组并去除重复项。 - kbatsconfig.json
文件中,你可以在“compilerOptions”中添加"downlevelIteration": true
来启用下级迭代。 - Vincevar 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次操作
过滤器:每秒约445k次操作
lodash:每秒约308k次操作
for循环:每秒约225k次操作
一条评论指出,我的设置变量之一导致循环领先于其他操作,因为它不必初始化一个空数组来写入。我同意这一点,所以我重写了测试以平衡竞争条件,并包括了一个更快的选项。
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()
调用时导致速度变慢的情况,并包含其他用户在他们的答案中建议的一些优化。我简化了这个答案中的最佳部分,并将其转化为一个好用的函数:
function mergeUnique(arr1, arr2){
return arr1.concat(arr2.filter(function (item) {
return arr1.indexOf(item) === -1;
}));
}
const mergeUnique = (a, b) => a.concat(b.filter(v => a.indexOf(v) === -1))
- mad.meeshfindIndex
在 filter()
函数中通过对象属性值查找对象的索引,如下所示:
const index = arr1.findIndex(i => i.id === item.id);
- askepottThe ES6提供了一种通过解构和set来合并多个数组且不包含重复项的单行解决方案。
const array1 = ['a','b','c'];
const array2 = ['c','c','d','e'];
const array3 = [...new Set([...array1,...array2])];
console.log(array3); // ["a", "b", "c", "d", "e"]
b
到a
) :a=a.concat(b);
从数组a
中删除重复项 (就地操作) :a=a.filter((i,p)=>a.indexOf(i)===p);
- ashleedawg