someSource()
.reduce(...)
.filter(...)
.map(...)
// and now you want to concat array2 and deduplicate:
.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)
// and keep chaining stuff
.map(...)
.find(...)
// etc
var set1 = {"Vijendra":true, "Singh":true}
var set2 = {"Singh":true, "Shakya":true}
// Merge second object into first
function merge(set1, set2){
for (var key in set2){
if (set2.hasOwnProperty(key))
set1[key] = set2[key]
}
return set1
}
merge(set1, set2)
// Create set from array
function setify(array){
var result = {}
for (var item in array){
if (array.hasOwnProperty(item))
result[array[item]] = true
}
return result
}
14
Array.prototype.add = function(b){
var a = this.concat(); // clone current object
if(!b.push || !b.length) return a; // if b is not an array, or empty, then return a unchanged
if(!a.length) return b.concat(); // if original is empty, return b
// go through all the elements of b
for(var i = 0; i < b.length; i++){
// if b's value is not in a, then add it
if(a.indexOf(b[i]) == -1) a.push(b[i]);
}
return a;
}
// Example:
console.log([1,2,3].add([3, 4, 5])); // will output [1, 2, 3, 4, 5]
function merge(a, b) {
var hash = {}, i;
for (i=0; i<a.length; i++) {
hash[a[i]]=true;
}
for (i=0; i<b.length; i++) {
hash[b[i]]=true;
}
return Object.keys(hash);
}
8
刚扔掉我的两分钱 .
function mergeStringArrays(a, b){
var hash = {};
var ret = [];
for(var i=0; i < a.length; i++){
var e = a[i];
if (!hash[e]){
hash[e] = true;
ret.push(e);
}
}
for(var i=0; i < b.length; i++){
var e = b[i];
if (!hash[e]){
hash[e] = true;
ret.push(e);
}
}
return ret;
}
var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b);
var d = c.filter(function (item, pos) {return c.indexOf(item) == pos});
// d is [1,2,3,101,10]
var 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 ops / s 过滤器:~445k ops / s lodash:308k ops / s for循环:225k ops / s
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));
Array.prototype.merge = function(/* variable number of arrays */){
for(var i = 0; i < arguments.length; i++){
var array = arguments[i];
for(var j = 0; j < array.length; j++){
if(this.indexOf(array[j]) === -1) {
this.push(array[j]);
}
}
}
return this;
};
一个更好的阵列合并功能 .
31
//Array.indexOf was introduced in javascript 1.6 (ECMA-262)
//We need to implement it explicitly for other browsers,
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt, from)
{
var len = this.length >>> 0;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
//now, on to the problem
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var merged = array1.concat(array2);
var t;
for(i = 0; i < merged.length; i++)
if((t = merged.indexOf(i + 1, merged[i])) != -1)
{
merged.splice(t, 1);
i--;//in case of multiple occurrences
}
Array.prototype.indexOf = Array.prototype.indexOf || function(elt)
{
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0) ? Math.ceil(from): Math.floor(from);
if (from < 0)from += len;
for (; from < len; from++)
{
if (from in this && this[from] === elt)return from;
}
return -1;
};
2
它可以使用Set完成 .
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1.concat(array2);
var tempSet = new Set(array3);
array3 = Array.from(tempSet);
//show output
document.body.querySelector("div").innerHTML = JSON.stringify(array3);
<div style="width:100%;height:4rem;line-height:4rem;background-color:steelblue;color:#DDD;text-align:center;font-family:Calibri" >
temp text
</div>
2
最好的解决方案......
您可以通过点击直接在浏览器控制台中查看...
没有重复
a = [1, 2, 3];
b = [3, 2, 1, "prince"];
a.concat(b.filter(function(el) {
return a.indexOf(el) === -1;
}));
30 回答
我的一分半便士:
关于这个的好处是性能,你通常在使用数组时会链接像filter,map等方法,所以你可以添加该行,它将使用array1连续和重复删除array2,而不需要引用更高版本一个(当你链接你没有的方法时),例如:
(我不喜欢污染Array.prototype,这将是尊重链的唯一方式 - 定义一个新函数会破坏它 - 所以我认为这样的事情是唯一的方法来实现)
你可以使用Underscore.js => uniq 来实现它:
它将打印 ["Vijendra", "Singh", "Shakya"] .
在Dojo 1.6中
Update
查看工作代码 .
http://jsfiddle.net/UAxJa/1/
这是使用spread operator和数组泛型的ECMAScript 6解决方案 .
目前它只适用于Firefox,可能还适用于Internet Explorer Technical Preview .
但是如果你使用Babel,你现在可以拥有它 .
你为什么不用一个物体?看起来你正试图模拟一套 . 但是,这不会保留订单 .
最简单的方法是使用
concat()
合并数组,然后使用filter()
删除重复项,或者使用concat()
然后将合并后的数组放在Set()
中 .第一种方式:
第二种方式(但在UI上具有性能影响):
你可以用ECMAScript 6简单地完成它,
使用spread operator连接数组 .
使用Set创建一组不同的元素 .
再次使用spread运算符将Set转换为数组 .
只需避开嵌套循环(O(n ^ 2))和
.indexOf()
(O(n)) .刚扔掉我的两分钱 .
这是我经常使用的一种方法,它使用一个对象作为hashlookup表来进行重复检查 . 假设散列是O(1),那么这在O(n)中运行,其中n是a.length b.length . 老实说,我不知道浏览器如何处理哈希,但它在数千个数据点上表现良好 .
使用Underscore.js或Lo-Dash,您可以:
http://underscorejs.org/#union
http://lodash.com/docs#union
首先连接两个数组,然后只筛选出唯一的项 .
http://jsfiddle.net/simo/98622/
编辑
正如@Dmitry所建议的那样(参见下面的第二条评论),更明智的解决方案是在与
a
连接之前过滤出b
中的唯一项目ES6
或
或
假设原始数组不需要重复数据删除,这应该非常快,保留原始顺序,并且不会修改原始数组...
用法:
为了它...这是一个单行解决方案:
不是特别可读,但它可以帮助某人:
应用reduce函数,并将初始累加器值设置为空数组 .
reduce函数使用concat将每个子数组附加到累加器数组 .
结果作为构造函数参数传递,以创建新的
Set
.扩展运算符用于将
Set
转换为数组 .sort()
函数应用于新数组 .ES2015的功能方法
在功能方法之后,两个
Array
的union
只是concat
和filter
的组成 . 为了提供最佳性能,我们采用了原生的Set
数据类型,该类型针对属性查找进行了优化 .无论如何,与
union
函数结合的关键问题是如何处理重复项 . 以下排列是可能的:前两个排列很容易用单一功能处理 . 但是,最后两个更复杂,因为只要依赖
Set
查找,就无法处理它们 . 由于切换到普通的旧式Object
属性查找会导致严重的性能损失,因此以下实现只忽略第三和第四个排列 . 您必须构建一个单独的union
版本才能支持它们 .从这里可以轻松实现一个
unionn
函数,该函数接受任意数量的数组(受naomik的评论启发):事实证明
unionn
只是foldl
(又名Array.prototype.reduce
),它以union
为减速器 . 注意:由于实现不使用额外的累加器,因此在不使用参数的情况下应用它时会抛出错误 .这是一个稍微不同的循环 . 通过最新版Chrome中的一些优化,它是解决两个阵列联合的最快方法(Chrome 38.0.2111) .
http://jsperf.com/merge-two-arrays-keeping-only-unique-values
while循环:~589k ops / s
过滤器:~445k ops / s
lodash:308k ops / s
for循环:225k ops / s
注释指出我的一个设置变量导致我的循环领先于其余变量,因为它不必初始化要写入的空数组 . 我同意这一点,所以我已经将测试改写为公平竞争,并且包括更快的选项 .
http://jsperf.com/merge-two-arrays-keeping-only-unique-values/21
在这个替代解决方案中,我用've combined one answer' s关联数组解决方案来消除循环中的
.indexOf()
调用使用第二个循环减慢了很多事情,并包括其他用户在其答案中建议的一些其他优化 .这里的最佳答案是每个值(i-1)上的双循环仍然明显变慢 . lodash仍然很强大,我还是会推荐给那些不介意在他们的项目中添加库的人 . 对于那些不想要的人来说,我的while循环仍然是一个很好的答案,过滤器的答案在这里有很强的表现,在撰写本文时,最新的Canary Chrome(44.0.2360)测试结果一目了然 .
如果你想提高速度,请查看Mike's answer和Dan Stocker's answer . 在经历了几乎所有可行的答案之后,这些是迄今为止所有结果中最快的 .
仅合并数组(不删除重复项)
ES5版本使用Array.concat:
ES6版本使用解构
由于没有'built in'方法来删除重复项(ECMA-262实际上有
Array.forEach
这对此很好),我们必须手动执行:然后,使用它:
这也将保留数组的顺序(即,不需要排序) .
由于许多人对
Array.prototype
和for in
循环的原型扩充感到恼火,因此这是一种使用它的侵入性较小的方法:对于那些有幸使用ES5可用的浏览器的人,你可以像这样使用
Object.defineProperty
:简化simo's answer并将其转换为一个很好的功能 .
合并无限数量的数组或非数组并保持其唯一性:
一个更好的阵列合并功能 .
其他浏览器的
indexOf
方法实现取自MDC对于ES6,只需一行:
新解决方案(使用
Array.prototype.indexOf
和Array.prototype.concat
):用法:
Array.prototype.indexOf(用于Internet Explorer):
它可以使用Set完成 .
最好的解决方案......
您可以通过点击直接在浏览器控制台中查看...
没有重复
有重复
如果您想要没有重复,您可以从这里尝试更好的解决方案 - Shouting Code .
试试Chrome浏览器控制台
输出:
使用Set(ECMAScript 2015),它将如此简单:
合并两个数组并删除es6中的副本