我有两个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中合并两个数组,以便从每个数组中只获得唯一的项目,其顺序与它们插入原始数组的顺序相同?
当前回答
编辑:
只有在项目很少的情况下,第一种解决方案才是最快的。当项目超过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
其他回答
如果像我一样,您需要支持较旧的浏览器,这适用于IE6+
function es3Merge(a, b) {
var hash = {},
i = (a = a.slice(0)).length,
e;
while (i--) {
hash[a[i]] = 1;
}
for (i = 0; i < b.length; i++) {
hash[e = b[i]] || a.push(e);
}
return a;
};
http://jsperf.com/merge-two-arrays-keeping-only-unique-values/22
在Dojo 1.6中+
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);
});
使现代化
参见工作代码。
http://jsfiddle.net/UAxJa/1/
var MergeArrays=function(arrayOne, arrayTwo, equalityField) {
var mergeDictionary = {};
for (var i = 0; i < arrayOne.length; i++) {
mergeDictionary[arrayOne[i][equalityField]] = arrayOne[i];
}
for (var i = 0; i < arrayTwo.length; i++) {
mergeDictionary[arrayTwo[i][equalityField]] = arrayTwo[i];
}
return $.map(mergeDictionary, function (value, key) { return value });
}
利用字典和Jquery,您可以合并这两个数组,而不会得到重复项。在我的示例中,我在对象上使用给定的字段,但可能只是对象本身。
使用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
这很快,可以整理任意数量的数组,并且可以处理数字和字符串。
function collate(a){ // Pass an array of arrays to collate into one array
var h = { n: {}, s: {} };
for (var i=0; i < a.length; i++) for (var j=0; j < a[i].length; j++)
(typeof a[i][j] === "number" ? h.n[a[i][j]] = true : h.s[a[i][j]] = true);
var b = Object.keys(h.n);
for (var i=0; i< b.length; i++)
b[i]=Number(b[i]);
return b.concat(Object.keys(h.s));
}
> a = [ [1,2,3], [3,4,5], [1,5,6], ["spoon", "fork", "5"] ]
> collate( a )
[1, 2, 3, 4, 5, 6, "5", "spoon", "fork"]
如果你不需要区分5和“5”,那么
function collate(a){
var h = {};
for (i=0; i < a.length; i++) for (var j=0; j < a[i].length; j++)
h[a[i][j]] = typeof a[i][j] === "number";
for (i=0, b=Object.keys(h); i< b.length; i++)
if (h[b[i]])
b[i]=Number(b[i]);
return b;
}
[1, 2, 3, 4, "5", 6, "spoon", "fork"]
可以。
如果你不介意(或者更愿意)所有值都以字符串结尾,那么就这样:
function collate(a){
var h = {};
for (var i=0; i < a.length; i++)
for (var j=0; j < a[i].length; j++)
h[a[i][j]] = true;
return Object.keys(h)
}
["1", "2", "3", "4", "5", "6", "spoon", "fork"]
如果您实际上不需要数组,但只想收集唯一值并对其进行迭代,那么(在大多数浏览器(和node.js)中):
h = new Map();
for (i=0; i < a.length; i++)
for (var j=0; j < a[i].length; j++)
h.set(a[i][j]);
这可能更好。