我有两个JavaScript数组:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
我希望输出为:
var array3 = ["Vijendra","Singh","Shakya"];
输出数组应该删除重复的单词。
如何在JavaScript中合并两个数组,以便我只按照它们插入原始数组的顺序从每个数组中获取唯一项?
答案 0 :(得分:1438)
仅合并数组(不删除重复项)
Array.concat
:var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1.concat(array2); // Merges both arrays
// [ 'Vijendra', 'Singh', 'Singh', 'Shakya' ]
const array1 = ["Vijendra","Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = [...array1, ...array2];
由于没有“内置”方式来删除重复项(ECMA-262实际上有Array.forEach
这对此很有用),我们必须手动执行:
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));
对于那些有幸使用ES5可用的浏览器的人,您可以像这样使用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;
}
});
答案 1 :(得分:548)
使用Underscore.js或Lo-Dash,您可以:
_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]
答案 2 :(得分:228)
首先连接两个数组,然后只过滤掉唯一的项目。
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]
http://jsfiddle.net/simo/98622/
根据@Dmitry的建议(请参阅下面的第二条评论),更明智的解决方案是在与b
连接之前过滤a
中的唯一项
var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b.filter(function (item) {
return a.indexOf(item) < 0;
}));
// d is [1,2,3,101,10]
答案 3 :(得分:151)
这是使用spread operator和数组泛型的ECMAScript 6解决方案。
目前它只适用于Firefox,可能还适用于Internet Explorer Technical Preview。
但如果您使用Babel,则可以立即使用。
// Input: [ [1, 2, 3], [101, 2, 1, 10], [2, 1] ]
// Output: [1, 2, 3, 101, 10]
function mergeDedupe(arr)
{
return [...new Set([].concat(...arr))];
}
答案 4 :(得分:125)
array1.push(...array2) // => don't remove duplication
[...array1,...array2] // => don't remove duplication
[...new Set([...array1 ,...array2])]; // => remove duplication
答案 5 :(得分:48)
使用Set(ECMAScript 2015),它将如此简单:
const array1 = ["Vijendra", "Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = Array.from(new Set(array1.concat(array2)));
答案 6 :(得分:33)
这是对循环略有不同的看法。通过最新版Chrome中的一些优化,它是解决两个阵列联合的最快方法(Chrome 38.0.2111)。
http://jsperf.com/merge-two-arrays-keeping-only-unique-values
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
一条评论指出我的一个设置变量导致我的循环领先于其余部分,因为它没有必要初始化一个空数组来写入。我同意这一点,所以我已经将测试改写为公平竞争,并且包括更快的选择。
http://jsperf.com/merge-two-arrays-keeping-only-unique-values/52
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()
调用,这会使第二个循环减慢很多事情,并包括一些其他用户在其答案中也提出的其他优化措施。
这里的每个值(i-1)上的双循环的最佳答案仍然明显变慢。 lodash仍然很强大,我仍然会推荐给那些不介意在他们的项目中添加库的人。对于那些不想要的人,我的while循环仍然是一个很好的答案,过滤器的答案在这里有很强的表现,在我的测试中击败了最新的Canary Chrome(44.0.2360)
如果您希望提高速度,请查看Mike's answer和Dan Stocker's answer。在经历了几乎所有可行的答案之后,这些是迄今为止所有结果中最快的。
答案 7 :(得分:31)
您只需使用ECMAScript 6
即可var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
答案 8 :(得分:19)
合并两个数组并删除es6中的副本
let arr1 = [3, 5, 2, 2, 5, 5];
let arr2 = [2, 1, 66, 5];
let unique = [...new Set([...arr1,...arr2])];
console.log(unique);
// [ 3, 5, 2, 1, 66 ]
答案 9 :(得分:16)
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;
};
更好的阵列合并功能。
答案 10 :(得分:15)
避开嵌套循环(O(n ^ 2))和.indexOf()
(+ O(n))。
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);
}
答案 11 :(得分:14)
只要投入我的两分钱。
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;
}
这是一个我经常使用的方法,它使用一个对象作为hashlookup表来进行重复检查。假设散列是O(1),那么这在O(n)中运行,其中n是a.length + b.length。老实说,我不知道浏览器如何处理散列,但它在数千个数据点上表现良好。
答案 12 :(得分:14)
基于jsperf,将两个数组合并为一个新数组的最快方法如下:
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%:
var a = [...new Set([...array1 ,...array2])];
可接受的答案慢了55%(写的时间更长)
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);
}
}
答案 13 :(得分:13)
基于ES6的联合解决方案
let arr1 = [1,2,3,4,5];
let arr2 = [3,4,5,6];
let result = [...new Set([...arr1, ...arr2])];
console.log(result);
答案 14 :(得分:13)
为什么不使用对象?看起来你正试图模拟一套。但是,这不会保留订单。
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
}
答案 15 :(得分:8)
最佳解决方案......
您可以通过点击...
直接在浏览器控制台中查看a = [1, 2, 3];
b = [3, 2, 1, "prince"];
a.concat(b.filter(function(el) {
return a.indexOf(el) === -1;
}));
["prince", "asish", 5].concat(["ravi", 4])
如果你想要没有重复,你可以从这里尝试更好的解决方案 - Shouting Code。
[1, 2, 3].concat([3, 2, 1, "prince"].filter(function(el) {
return [1, 2, 3].indexOf(el) === -1;
}));
试用Chrome浏览器控制台
f12 > console
输出:
["prince", "asish", 5, "ravi", 4]
[1, 2, 3, "prince"]
答案 16 :(得分:8)
简化simo's answer并将其转换为一个很好的功能。
function mergeUnique(arr1, arr2){
return arr1.concat(arr2.filter(function (item) {
return arr1.indexOf(item) === -1;
}));
}
答案 17 :(得分:8)
我的一分半便士:
Array.prototype.concat_n_dedupe = function(other_array) {
return this
.concat(other_array) // add second
.reduce(function(uniques, item) { // dedupe all
if (uniques.indexOf(item) == -1) {
uniques.push(item);
}
return uniques;
}, []);
};
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var result = array1.concat_n_dedupe(array2);
console.log(result);
答案 18 :(得分:7)
你可以使用Underscore.js's =&gt;来实现它。的 uniq的强>:
array3 = _.uniq(array1.concat(array2))
console.log(array3)
会打印 [“Vijendra”,“Singh”,“Shakya”] 。
答案 19 :(得分:6)
//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
}
其他浏览器的indexOf
方法的实现取自MDC
答案 20 :(得分:6)
可以使用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>
答案 21 :(得分:5)
新解决方案(使用Array.prototype.indexOf
和Array.prototype.concat
):
Array.prototype.uniqueMerge = function( a ) {
for ( var nonDuplicates = [], i = 0, l = a.length; i<l; ++i ) {
if ( this.indexOf( a[i] ) === -1 ) {
nonDuplicates.push( a[i] );
}
}
return this.concat( nonDuplicates )
};
用法:
>>> ['Vijendra', 'Singh'].uniqueMerge(['Singh', 'Shakya'])
["Vijendra", "Singh", "Shakya"]
Array.prototype.indexOf(适用于Internet Explorer):
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;
};
答案 22 :(得分:5)
array1.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)
关于这个的好处是性能,你通常在使用数组时会链接像filter,map等方法,所以你可以添加那行,它会连接并使用array1重复删除array2而不需要引用到后一个(当你链接你没有的方法时),例如:
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
(我不喜欢污染Array.prototype,这将是尊重链的唯一方式 - 定义一个新函数会打破它 - 所以我觉得这样的事情是唯一的方法来实现)
答案 23 :(得分:5)
对于ES6,只需一行:
a = [1, 2, 3, 4]
b = [4, 5]
[...new Set(a.concat(b))] // [1, 2, 3, 4, 5]
答案 24 :(得分:5)
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]
答案 25 :(得分:4)
- 实现这一目标的一种现代方法是简单地使用 spread operator 。
- 为避免重复,我们可以有效地使用 Sets ; 集合默认情况下不允许重复。
- 要从Set中获取数组结果,我们可以使用 Array.from()
所以,这是您的情况的演示-
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var resArr = Array.from(new Set([...array1, ...array2]));
console.log(resArr);
答案 26 :(得分:4)
以下是带有对象数组的对象的选项:
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}]
答案 27 :(得分:4)
使用此discovery,我为中等大小的阵列创建了非常快速的解决方案,并将性能与所选解决方案进行了比较(我将解决方案命名为K
)。该解决方案修改输入数组
function K(arr1,arr2) {
let r=[], h={};
while(arr1.length) {
let e = arr1.shift();
if(!h[e]) h[e]=1 && r.push(e);
}
while(arr2.length) {
let e = arr2.shift();
if(!h[e]) h[e]=1 && r.push(e);
}
return r;
}
// TEST
var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
console.log(K(array1,array2))
今天2020.10.15,我针对选定的解决方案在Chrome v86,Safari v13.1.2和Firefox v81的MacOs HighSierra 10.13.6上进行了测试。
对于所有浏览器
我们应该在这里注意,对于Chrome上的大型阵列,K解决方案可能会变慢-详细信息here
我执行2个测试用例:
关于解决方案 A, B, C, D, E, F, G, H, I, J, K(我的), L, M 显示在以下片段中
// https://stackoverflow.com/a/10499519/860099
function A(arr1,arr2) {
return _.union(arr1,arr2)
}
// https://stackoverflow.com/a/53149853/860099
function B(arr1,arr2) {
return _.unionWith(arr1, arr2, _.isEqual);
}
// https://stackoverflow.com/a/27664971/860099
function C(arr1,arr2) {
return [...new Set([...arr1,...arr2])]
}
// https://stackoverflow.com/a/48130841/860099
function D(arr1,arr2) {
return Array.from(new Set(arr1.concat(arr2)))
}
// https://stackoverflow.com/a/23080662/860099
function E(arr1,arr2) {
return arr1.concat(arr2.filter((item) => arr1.indexOf(item) < 0))
}
// https://stackoverflow.com/a/60421828/860099
function F(array1, array2){
for (var i = 0; i < array2.length; i++)
if (array1.indexOf(array2[i]) === -1)
array1.push(array2[i]);
return array1;
}
// https://stackoverflow.com/a/28631880/860099
function G(arr1,arr2) {
var hash = {};
var i;
for (i = 0; i < arr1.length; i++) {
hash[arr1[i]] = true;
}
for (i = 0; i < arr2.length; i++) {
hash[arr2[i]] = true;
}
return Object.keys(hash);
}
// https://stackoverflow.com/a/13847481/860099
function H(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;
}
// https://stackoverflow.com/a/32108675/860099
function I(a1, a2) {
var ai = [];
for (var x = 0; x < a2.length; x++) {
ai.push(x)
};
for (var x = 0; x < a1.length; x++) {
for (var y = 0; y < ai.length; y++) {
if (a1[x] === a2[ai[y]]) {
ai.splice(y, 1);
y--;
}
}
}
for (var x = 0; x < ai.length; x++) {
a1.push(a2[ai[x]]);
}
return a1;
}
// https://stackoverflow.com/a/1584377/860099
function J(arr1,arr2) {
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;
}
return arrayUnique(arr1.concat(arr2));
}
// my
function K(arr1,arr2) {
let r=[], h={};
while(arr1.length) {
let e = arr1.shift();
if(!h[e]) h[e]=1 && r.push(e);
}
while(arr2.length) {
let e = arr2.shift();
if(!h[e]) h[e]=1 && r.push(e);
}
return r;
}
// https://stackoverflow.com/a/25120770/860099
function L(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;
}
// https://stackoverflow.com/a/39336712/860099
function M(arr1,arr2) {
const comp = f => g => x => f(g(x));
const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const afrom = apply(Array.from);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
const dedupe = comp(afrom) (createSet);
const union = xs => ys => {
const zs = createSet(xs);
return concat(xs) (
filter(x => zs.has(x)
? false
: zs.add(x)
) (ys));
}
return union(dedupe(arr1)) (arr2)
}
// -------------
// TEST
// -------------
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
[A,B,C,D,E,F,G,H,I,J,K,L,M].forEach(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==" crossorigin="anonymous"></script>
This shippet only presents functions used in performance tests - it not perform tests itself!
这是针对chrome的示例测试
答案 28 :(得分:4)
有很多用于合并两个数组的解决方案。 它们可以分为两个主要类别(除了使用诸如lodash或underscore.js之类的第三方库之外)。
a)合并两个数组并删除重复的项。
b)在组合项目之前先过滤掉它们。
// mutable operation(array1 is the combined array)
array1.push(...array2);
array1.unshift(...array2);
// immutable operation
const combined = array1.concat(array2);
const combined = [...array1, ...array2]; // ES6
统一数组的方法有很多,我个人建议以下两种方法。
// a little bit tricky
const merged = combined.filter((item, index) => combined.indexOf(item) === index);
const merged = [...new Set(combined)];
还有很多方法,但是由于其简单性,我个人建议以下代码。
const merged = array1.concat(array2.filter(secItem => !array1.includes(secItem)));
答案 29 :(得分:3)
为了它...这是一个单行解决方案:
const x = [...new Set([['C', 'B'],['B', 'A']].reduce( (a, e) => a.concat(e), []))].sort()
// ['A', 'B', 'C']
不是特别易读但可能有助于某人:
Set
。Set
转换为数组。sort()
函数应用于新数组。答案 30 :(得分:3)
var arr1 = [1, 3, 5, 6];
var arr2 = [3, 6, 10, 11, 12];
arr1.concat(arr2.filter(ele => !arr1.includes(ele)));
console.log(arr1);
output :- [1, 3, 5, 6, 10, 11, 12]
答案 31 :(得分:2)
看起来接受的答案是我测试中最慢的答案;
注意我正在通过键
合并2个对象数组<!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>
答案 32 :(得分:2)
最简单的过滤器解决方案:
SELECT udf.missingImage(c.images) FROM c
答案 33 :(得分:2)
我写了这个简单的函数,它接受多个数组参数。 与上面的解决方案几乎相同,只是有更实际的用例。此函数不会将重复值连接到一个数组中,以便它可以在稍后阶段删除它们。
短功能定义(仅9行)
/**
* This function merging only arrays unique values. It does not merges arrays in to array with duplicate values at any stage.
*
* @params ...args Function accept multiple array input (merges them to single array with no duplicates)
* it also can be used to filter duplicates in single array
*/
function arrayDeDuplicate(...args){
let set = new Set(); // init Set object (available as of ES6)
for(let arr of args){ // for of loops through values
arr.map((value) => { // map adds each value to Set object
set.add(value); // set.add method adds only unique values
});
}
return [...set]; // destructuring set object back to array object
// alternativly we culd use: return Array.from(set);
}
使用示例CODEPEN:
// SCENARIO
let a = [1,2,3,4,5,6];
let b = [4,5,6,7,8,9,10,10,10];
let c = [43,23,1,2,3];
let d = ['a','b','c','d'];
let e = ['b','c','d','e'];
// USEAGE
let uniqueArrayAll = arrayDeDuplicate(a, b, c, d, e);
let uniqueArraySingle = arrayDeDuplicate(b);
// OUTPUT
console.log(uniqueArrayAll); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 43, 23, "a", "b", "c", "d", "e"]
console.log(uniqueArraySingle); // [4, 5, 6, 7, 8, 9, 10]
答案 34 :(得分:2)
执行此操作的最简单方法是使用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);
答案 35 :(得分:2)
遵循功能方法,union
两个Array
只是concat
和filter
的组合。为了提供最佳性能,我们采用原生的Set
数据类型,该类型针对属性查找进行了优化。
无论如何,与union
函数结合使用的关键问题是如何处理重复项。以下排列是可能的:
Array A + Array B
[unique] + [unique]
[duplicated] + [unique]
[unique] + [duplicated]
[duplicated] + [duplicated]
前两个排列很容易用一个函数处理。但是,最后两个更复杂,因为只要您依赖Set
查找,就无法处理它们。由于切换到普通的旧Object
属性查找会导致严重的性能损失,因此以下实现忽略了第三和第四个排列。您必须构建一个单独版本的union
来支持它们。
// small, reusable auxiliary functions
const comp = f => g => x => f(g(x));
const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const afrom = apply(Array.from);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
// de-duplication
const dedupe = comp(afrom) (createSet);
// the actual union function
const union = xs => ys => {
const zs = createSet(xs);
return concat(xs) (
filter(x => zs.has(x)
? false
: zs.add(x)
) (ys));
}
// mock data
const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];
// here we go
console.log( "unique/unique", union(dedupe(xs)) (ys) );
console.log( "duplicated/unique", union(xs) (ys) );
&#13;
从这里开始,实现unionn
函数变得微不足道,该函数接受任意数量的数组(受naomik评论的启发):
// small, reusable auxiliary functions
const uncurry = f => (a, b) => f(a) (b);
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc);
const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
// union and unionn
const union = xs => ys => {
const zs = createSet(xs);
return concat(xs) (
filter(x => zs.has(x)
? false
: zs.add(x)
) (ys));
}
const unionn = (head, ...tail) => foldl(union) (head) (tail);
// mock data
const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];
const zs = [0,1,2,3,4,5,6,7,8,9];
// here we go
console.log( unionn(xs, ys, zs) );
&#13;
结果unionn
只是foldl
(又名Array.prototype.reduce
),它将union
作为缩减器。注意:由于实现没有使用额外的累加器,因此在没有参数的情况下应用它时会抛出错误。
答案 36 :(得分:2)
在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);
});
<强>更新强>
参见工作代码。
答案 37 :(得分:2)
合并无限数量的数组或非数组并使其保持唯一:
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]
答案 38 :(得分:2)
假设原始数组不需要重复数据删除,这应该非常快,保留原始顺序,并且不会修改原始数组......
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' ]
答案 39 :(得分:2)
我知道这个问题与对象数组无关,但是搜索者的确到了这里。
因此值得将来的读者添加正确的ES6合并方式,然后删除重复项
对象数组:
var arr1 = [ {a: 1}, {a: 2}, {a: 3} ];
var arr2 = [ {a: 1}, {a: 2}, {a: 4} ];
var arr3 = arr1.concat(arr2.filter( ({a}) => !arr1.find(f => f.a == a) ));
// [ {a: 1}, {a: 2}, {a: 3}, {a: 4} ]
答案 40 :(得分:1)
var array1 = ["one","two"];
var array2 = ["two", "three"];
var collectionOfTwoArrays = [...array1, ...array2];
var uniqueList = array => [...new Set(array)];
console.log('Collection :');
console.log(collectionOfTwoArrays);
console.log('Collection without duplicates :');
console.log(uniqueList(collectionOfTwoArrays));
答案 41 :(得分:1)
减少它们!!!
此替代方案不是显式合并和重复数据消除,而是采用一个数组并用另一个数组进行缩减,以便可以通过累积行为迭代和解构第一个数组的每个值,而通过利用持久性来忽略已经包含的值数组的原因在于递归。
array2.reduce(reducer, array1.reduce(reducer, []))
测试示例:
var array1 = ["Vijendra","Singh","Singh"];
var array2 = ["Singh", "Shakya", "Shakya"];
const reducer = (accumulator, currentValue) => accumulator.includes(currentValue) ? accumulator : [...accumulator, currentValue];
console.log(
array2.reduce(reducer, array1.reduce(reducer, []))
);
// a reduce on first array is needed to ensure a deduplicated array used as initial value on the second array being reduced
结论
希望避免无聊的for-each
方法时更加优雅和有用(不是无用)。
在重复数据删除方面有concat()
个限制。
无需像Underscore.js,JQuery或Lo-Dash这样的外部库,也无需创建任何内置函数来实现所需的合并和重复数据删除效果。
哦,嘿!,它可以单线完成!!!
答案 42 :(得分:1)
如果您不想重复特定属性(例如ID)
let noDuplicate = array1.filter ( i => array2.findIndex(a => i.id==a.id)==-1 );
let result = [...noDuplicate, ...array2];
答案 43 :(得分:1)
构建了一个测试器来检查一些以性能为导向的答案的速度。随意添加更多。到目前为止,Set
是最简单和最快的选项(随着记录数量的增加,幅度更大),至少对于简单的 Number
类型是这样。
const records = 10000, //max records per array
max_int = 100, //max integer value per array
dup_rate = .5; //rate of duplication
let perf = {}, //performance logger,
ts = 0,
te = 0,
array1 = [], //init arrays
array2 = [],
array1b = [],
array2b = [],
a = [];
//populate randomized arrays
for (let i = 0; i < records; i++) {
let r = Math.random(),
n = r * max_int;
if (Math.random() < .5) {
array1.push(n);
r < dup_rate && array2.push(n);
} else {
array2.push(n);
r < dup_rate && array1.push(n);
}
}
//simple deep copies short of rfdc, in case someone wants to test with more complex data types
array1b = JSON.parse(JSON.stringify(array1));
array2b = JSON.parse(JSON.stringify(array2));
console.log('Records in Array 1:', array1.length, array1b.length);
console.log('Records in Array 2:', array2.length, array2b.length);
//test method 1 (jsperf per @Pitouli)
ts = performance.now();
for (let i = 0; i < array2.length; i++)
if (array1.indexOf(array2[i]) === -1)
array1.push(array2[i]); //modifies array1
te = performance.now();
perf.m1 = te - ts;
console.log('Method 1 merged', array1.length, 'records in:', perf.m1);
array1 = JSON.parse(JSON.stringify(array1b)); //reset array1
//test method 2 (classic forEach)
ts = performance.now();
array2.forEach(v => array1.includes(v) ? null : array1.push(v)); //modifies array1
te = performance.now();
perf.m2 = te - ts;
console.log('Method 2 merged', array1.length, 'records in:', perf.m2);
//test method 3 (Simplest native option)
ts = performance.now();
a = [...new Set([...array1, ...array2])]; //does not modify source arrays
te = performance.now();
perf.m3 = te - ts;
console.log('Method 3 merged', a.length, 'records in:', perf.m3);
//test method 4 (Selected Answer)
ts = performance.now();
a = array1.concat(array2); //does not modify source arrays
for (let i = 0; i < a.length; ++i) {
for (let j = i + 1; j < a.length; ++j) {
if (a[i] === a[j])
a.splice(j--, 1);
}
}
te = performance.now();
perf.m4 = te - ts;
console.log('Method 4 merged', a.length, 'records in:', perf.m4);
//test method 5 (@Kamil Kielczewski)
ts = performance.now();
function K(arr1, arr2) {
let r = [],
h = {};
while (arr1.length) {
let e = arr1.shift(); //modifies array1
if (!h[e]) h[e] = 1 && r.push(e);
}
while (arr2.length) {
let e = arr2.shift(); //modifies array2
if (!h[e]) h[e] = 1 && r.push(e);
}
return r;
}
a = K(array1, array2);
te = performance.now();
perf.m5 = te - ts;
console.log('Method 5 merged', a.length, 'records in:', perf.m4);
array1 = JSON.parse(JSON.stringify(array1b)); //reset array1
array2 = JSON.parse(JSON.stringify(array2b)); //reset array2
for (let i = 1; i < 6; i++) {
console.log('Method:', i, 'speed is', (perf['m' + i] / perf.m1 * 100).toFixed(2), '% of Method 1');
}
答案 44 :(得分:1)
就计算时间而言,这是最有效的一个。它还保留了元素的初始顺序。
首先从第二个数组中过滤掉所有重复项,然后将剩下的内容连接到第一个数组。
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];
}
答案 45 :(得分:1)
这很简单,可以使用jQuery在一行中完成:
var arr1 = ['Vijendra', 'Singh'], arr2 =['Singh', 'Shakya'];
$.unique(arr1.concat(arr2))//one line
["Vijendra", "Singh", "Shakya"]
答案 46 :(得分:1)
我学会了一种用扩展运算符连接两个数组的小巧方法:
var array1 = ['tom', 'dick', 'harry'];
var array2 = ['martin', 'ricky'];
array1.push(...array2);
&#34; ...&#34; spread运算符将以下数组拆分为单个项,然后push可以将它们作为单独的参数处理。
答案 47 :(得分:1)
如果合并对象数组,请考虑使用lodash UnionBy
函数,该函数可用于设置自定义谓词比较对象:
import { unionBy } from 'lodash';
const a = [{a: 1, b: 2}];
const b = [{a: 1, b: 3}];
const c = [{a: 2, b: 4}];
const result = UnionBy(a,b,c, x => x.a);
结果是:[{ a: 1; b: 2 }, { a: 2; b: 4 }]
在结果中使用数组中的第一个传递的匹配
答案 48 :(得分:1)
这是一个简单的例子:
var unique = function(array) {
var unique = []
for (var i = 0; i < array.length; i += 1) {
if (unique.indexOf(array[i]) == -1) {
unique.push(array[i])
}
}
return unique
}
var uniqueList = unique(["AAPL", "MSFT"].concat(["MSFT", "BBEP", "GE"]));
我们定义unique(array)
以删除冗余元素,并使用concat
函数组合两个数组。
答案 49 :(得分:1)
这是我的第二个答案,但我相信最快?我希望有人检查我并在评论中回复。
我的第一次尝试达到了大约99k ops / sec,这就是说390k ops / sec与另一个领先的jsperf测试140k(对我而言)。
http://jsperf.com/merge-two-arrays-keeping-only-unique-values/26
这次尝试尽量减少尽可能多的数组交互,看起来我已经获得了一些性能。
function findMerge(a1, a2) {
var len1 = a1.length;
for (var x = 0; x < a2.length; x++) {
var found = false;
for (var y = 0; y < len1; y++) {
if (a2[x] === a1[y]) {
found = true;
break;
}
}
if(!found){
a1.push(a2.splice(x--, 1)[0]);
}
}
return a1;
}
编辑:我对我的功能进行了一些更改,与jsperf网站上的其他人相比,性能更加突出。
答案 50 :(得分:1)
使用Lodash
我发现@ GijsjanB的答案很有用但我的数组包含了许多属性的对象,所以我不得不使用其中一个属性去除它们。
以下是使用myAudioCtx.close();
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 }]
。
答案 51 :(得分:1)
作为LiraNuna的一部分的一线解决方案:
let array1 = ["Vijendra","Singh"];
let array2 = ["Singh", "Shakya"];
// Merges both arrays
let array3 = array1.concat(array2);
//REMOVE DUPLICATE
let removeDuplicate = [...new Set(array3)];
console.log(removeDuplicate);
答案 52 :(得分:1)
Array.prototype.union = function (other_array) {
/* you can include a test to check whether other_array really is an array */
other_array.forEach(function(v) { if(this.indexOf(v) === -1) {this.push(v);}}, this);
}
答案 53 :(得分:1)
由于集合不允许重复的元素,因此将从两个输入数组中的元素创建union。
例如:
var arr1 = ['1', '2', '3']
var arr2 = ['3', '4', '5']
var arr3 = [...new Set([...arr1, ...arr2])]
console.log(arr3);
//(5) ["1", "2", "3", "4", "5"]
答案 54 :(得分:1)
使用reduce func进行审核的另一种方法:
function mergeDistinct(arResult, candidate){
if (-1 == arResult.indexOf(candidate)) {
arResult.push(candidate);
}
return arResult;
}
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var arMerge = [];
arMerge = array1.reduce(mergeDistinct, arMerge);
arMerge = array2.reduce(mergeDistinct, arMerge);//["Vijendra","Singh","Shakya"];
答案 55 :(得分: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,您可以合并两个数组,而不是重复。在我的例子中,我在对象上使用给定的字段,但可能只是对象本身。
答案 56 :(得分:0)
这可以通过组合两个基本功能来实现。
const getUniqueMerge = (...arrs) => getUniqueArr(mergeArrs(...arrs))
const getUniqueArr = (array) => Array.from(new Set(array))
const mergeArrs = (...arrs) => [].concat(...arrs)
它可以处理无限个数组或值
console.log(getUniqueMerge(["Vijendra","Singh"],["Singh", "Shakya"])
// ["Vijendra", "Singh", "Shakya"]
console.log(getUniqueMerge(["Sheldon", "Cooper"], ["and", "Cooper", "Amy", "and"], "Farrah", "Amy", "Fowler"))
// ["Sheldon", "Cooper", "and", "Amy", "Farrah", "Fowler"]
答案 57 :(得分:0)
我认为这样工作更快。
removeDup = a => {
None
}
答案 58 :(得分:0)
您可以像union(array1, array2, array3, ...)
/**
* Merges two or more arrays keeping unique items. This method does
* not change the existing arrays, but instead returns a new array.
*/
function union<T>(...arrays: T[]) {
return [...new Set([...arrays].flat())];
}
由于具有flat()
功能,因此它是ES2019,但是您可以使用core-js将其作为polyfill来获取。这里的T
是TypeScript通用类型,如果不使用TypeScript,则可以将其删除。如果您使用的是TypeScript,请确保将"lib": ["es2019.array"]
添加到tsconfig.json
中的编译器选项中。
只需使用lodash _.union
答案 59 :(得分:0)
对于n个数组,您可以像这样获得联合。
Get___
答案 60 :(得分:0)
关心效率,但又想做内联
const s = new Set(array1);
array2.forEach(a => s.add(a));
const merged_array = [...s]; // optional: convert back in array type
答案 61 :(得分:0)
这是另一个使用 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));
答案 62 :(得分:0)
您可以尝试以下方法:
const union = (a, b) => Array.from(new Set([...a, ...b]));
console.log(union(["neymar","messi"], ["ronaldo","neymar"]));
答案 63 :(得分:0)
//1.merge two array into one array
var arr1 = [0, 1, 2, 4];
var arr2 = [4, 5, 6];
//for merge array we use "Array.concat"
let combineArray = arr1.concat(arr2); //output
alert(combineArray); //now out put is 0,1,2,4,4,5,6 but 4 reapeat
//2.same thing with "Spread Syntex"
let spreadArray = [...arr1, ...arr2];
alert(spreadArray); //now out put is 0,1,2,4,4,5,6 but 4 reapete
/*
if we need remove duplicate element method use are
1.Using set
2.using .filter
3.using .reduce
*/
答案 64 :(得分:0)
如果您仅使用underscore.js,则其中没有unionWith,unionBy
您可以尝试:
_.uniq(_.union(arr1, arr2), (obj) => obj.key)
(key是每个对象的key参数)
这将有助于在两个数组合并后获得唯一性。
答案 65 :(得分:0)
这是我的解决方案https://gist.github.com/4692150,其中包含深度等于且易于使用的结果:
function merge_arrays(arr1,arr2)
{
...
return {first:firstPart,common:commonString,second:secondPart,full:finalString};
}
console.log(merge_arrays(
[
[1,"10:55"] ,
[2,"10:55"] ,
[3,"10:55"]
],[
[3,"10:55"] ,
[4,"10:55"] ,
[5,"10:55"]
]).second);
result:
[
[4,"10:55"] ,
[5,"10:55"]
]
答案 66 :(得分:0)
之前刚刚写过同样的理由(适用于任意数量的数组):
/**
* 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; }
答案 67 :(得分:0)
Array.prototype.pushUnique = function(values)
{
for (var i=0; i < values.length; i++)
if (this.indexOf(values[i]) == -1)
this.push(values[i]);
};
尝试:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
array1.pushUnique(array2);
alert(array1.toString()); // Output: Vijendra,Singh,Shakya
答案 68 :(得分:0)
如果像我一样,你需要支持旧的浏览器,这适用于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
答案 69 :(得分:0)
用法:https://gist.github.com/samad-aghaei/7250ffb74ed80732debb1cbb14d2bfb0
var _uniqueMerge = function(opts, _ref){
for(var key in _ref)
if (_ref && _ref[key] && _ref[key].constructor && _ref[key].constructor === Object)
_ref[key] = _uniqueMerge((opts ? opts[key] : null), _ref[key] );
else if(opts && opts.hasOwnProperty(key))
_ref[key] = opts[key];
else _ref[key] = _ref[key][1];
return _ref;
}
答案 70 :(得分:0)
最好也是最简单的方法是使用函数&#34; some()&#34;返回true或false的JavaScript,指示数组是否包含对象的元素。你可以这样做:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1;
array2.forEach(function(elementArray2){
var isEquals = array1.some(function(elementArray1){
return elementArray1 === elementArray2;
})
if(!isEquals){
array3.push(elementArray2);
}
});
console.log(array3);
结果:
["Vijendra", "Singh", "Shakya"]
你希望......没有重复......
答案 71 :(得分:-1)
您可以合并结果并过滤重复项:
let combinedItems = [];
// items is an Array of arrays: [[1,2,3],[1,5,6],...]
items.forEach(currItems => {
if (currItems && currItems.length > 0) {
combinedItems = combinedItems.concat(currItems);
}
});
let noDuplicateItems = combinedItems.filter((item, index) => {
return !combinedItems.includes(item, index + 1);
});
答案 72 :(得分:-1)
/**
* De-duplicate an array keeping only unique values.
* Use hash table (js object) to filter-out duplicates.
* The order of array elements is maintained.
* This algorithm is particularly efficient for large arrays (linear time).
*/
function arrayUniqueFast(arr) {
var seen = {};
var result = [];
var i, len = arr.length;
for (i = 0; i < len; i++) {
var item = arr[i];
// hash table lookup
if (!seen[item]) {
result.push(item);
seen[item] = true;
}
}
return result;
}
///// test
var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var result = arrayUniqueFast(array1.concat(array2));
document.write('<br>result: ' + result);
要其他方法重复数组,请参阅我的基准:https://jsperf.com/de-duplicate-an-array-keeping-only-unique-values
答案 73 :(得分:-1)
大输入的更好选择是对数组进行排序。然后合并它们。
function sortFunction(a, b) {
return a - b;
}
arr1.sort(sortFunction);
arr2.sort(sortFunction);
function mergeDedup(arr1, arr2) {
var i = 0, j = 0, result = [];
while (i < arr1.length && j < arr2.length) {
if (arr1[i] < arr2[j]) {
writeIfNotSameAsBefore(result, arr1[i]);
i++;
}
else if (arr1[i] > arr2[j]) {
writeIfNotSameAsBefore(result, arr2[j]);
j++;
}
else {
writeIfNotSameAsBefore(result, arr1[i]);
i++;
j++;
}
}
while (i < arr1.length) {
writeIfNotSameAsBefore(result, arr1[i]);
i++;
}
while (j < arr2.length) {
writeIfNotSameAsBefore(result, arr2[j]);
j++;
}
return result;
}
function writeIfNotSameAsBefore(arr, item) {
if (arr[arr.length - 1] !== item) {
arr[arr.length] = item;
}
return arr.length;
}
排序将采用O(nlogn + mlogm),其中n和m是数组的长度,O(x)用于合并,其中x = Max(n,m);
答案 74 :(得分:-1)
给出两个没有重复的简单类型的排序数组,这将在O(n)时间内将它们合并,并且输出也将被排序。
import json
with open('test.json', 'r') as infile:
json.load(infile) # no problem
答案 75 :(得分:-1)
这很快,整理任意数量的数组,并使用数字和字符串。
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和&#34; 5&#34;,那么
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]);
可能更可取。
答案 76 :(得分:-1)
我在尝试做同样的事情时遇到了这个帖子,但我想尝试不同的东西。我刚刚编写了下面的功能。我还有另一个变量,'compareKeys',(键数组)用于进行浅层对象比较。我将来可能会把它改成一个函数。
无论如何,我没有包含该部分,因为它不适用于该问题。我还将我的代码放入jsperf中。编辑:我在jsperf修复了我的条目。与140k相比,我的功能大约为99k ops / sec。
代码:我首先创建一个可用索引的数组,然后通过迭代第一个数组来消除它们。最后,我通过使用两个数组之间不匹配的修剪下来的索引数组来推进“剩余”。
http://jsperf.com/merge-two-arrays-keeping-only-unique-values/26
function indiceMerge(a1, a2) {
var ai = [];
for (var x = 0; x < a2.length; x++) {
ai.push(x)
};
for (var x = 0; x < a1.length; x++) {
for (var y = 0; y < ai.length; y++) {
if (a1[x] === a2[ai[y]]) {
ai.splice(y, 1);
y--;
}
}
}
for (var x = 0; x < ai.length; x++) {
a1.push(a2[ai[x]]);
}
return a1;
}
答案 77 :(得分:-1)
var arr1 = ["neymar","messi"]
var arr2 = ["ronaldo","neymar"]
var arr3 = []
var obj = {}
for(var i = 0 ;i<arr1.length; i+=1){
if(!obj[arr1[i]]){
obj[arr1[i]] = true
arr3.push(arr1[i])
}
}
for(var i = 0 ;i<arr2.length; i+=1){
if(!obj[arr2[i]]){
obj[arr2[i]] = true
arr3.push(arr2[i])
}
}
console.log(arr3)
答案 78 :(得分:-1)
var a = [1,2,3]
var b = [1,2,4,5]
我喜欢一个衬里。这会将不同的b元素推送到
b.forEach(item => a.includes(item) ? null : a.push(item));
另一个不会修改
的版本var c = a.slice();
b.forEach(item => c.includes(item) ? null : c.push(item));
答案 79 :(得分:-1)
function set(a, b) {
return a.concat(b).filter(function(x,i,c) { return c.indexOf(x) == i; });
}
答案 80 :(得分:-1)
当我需要合并(或返回两个数组的并集)时,这是我使用的函数。
var union = function (a, b) {
for (var i = 0; i < b.length; i++)
if (a.indexOf(b[i]) === -1)
a.push(b[i]);
return a;
};
var a = [1, 2, 3, 'a', 'b', 'c'];
var b = [2, 3, 4, 'b', 'c', 'd'];
a = union(a, b);
//> [1, 2, 3, "a", "b", "c", 4, "d"]
var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = union(array1, array2);
//> ["Vijendra", "Singh", "Shakya"]
答案 81 :(得分:-1)
您可以使用 loadash unionWith -_.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>
答案 82 :(得分:-1)
使用:
Array.prototype.merge = function (arr) {
var key;
for(key in arr)
this[key] = arr[key];
};
答案 83 :(得分:-3)
const merge(...args)=>(new Set([].concat(...args)))
答案 84 :(得分:-4)
取两个数组a和b
var a = ['a','b','c'];
var b = ['d','e','f'];
var c = a.concat(b);
//c is now an an array with: ['a','b','c','d','e','f']