在JavaScript中获得两个数组的联合

时间:2010-09-02 17:58:43

标签: javascript arrays

假设我有一个[34, 35, 45, 48, 49]数组和另一个[48, 55]数组。如何获得[34, 35, 45, 48, 49, 55]的结果数组?

21 个答案:

答案 0 :(得分:76)

随着ES6与套装和splat操作员的到来(在仅在Firefox中工作时,检查兼容性表),你可以编写以下神秘的内容:

var a = [34, 35, 45, 48, 49];
var b = [48, 55];
var union = [...new Set([...a, ...b])];
console.log(union);

关于这一行的一点解释:[...a, ...b]连接两个数组,你也可以使用a.concat(b)new Set()创建一个集合,从而创建你的联盟。最后一个[...x]将其转换回数组。

答案 1 :(得分:42)

如果您不需要保留订单,请将45"45"视为相同:

function union_arrays (x, y) {
  var obj = {};
  for (var i = x.length-1; i >= 0; -- i)
     obj[x[i]] = x[i];
  for (var i = y.length-1; i >= 0; -- i)
     obj[y[i]] = y[i];
  var res = []
  for (var k in obj) {
    if (obj.hasOwnProperty(k))  // <-- optional
      res.push(obj[k]);
  }
  return res;
}

console.log(union_arrays([34,35,45,48,49], [44,55]));

答案 2 :(得分:42)

如果您使用库下划线,您可以这样写

var unionArr = _.union([34,35,45,48,49], [48,55]);
console.log(unionArr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

参考http://underscorejs.org/#union

答案 3 :(得分:16)

我可能在这里浪费时间在一个死线上。我只需要实现这一点,然后去看看我是否在浪费时间。

我真的很喜欢KennyTM的回答。这就是我如何解决这个问题。将密钥合并到散列中以自然地消除重复,然后提取密钥。如果你真的有jQuery,你可以利用它的好东西使这成为一个2行问题,然后将其转换为扩展。 jQuery中的each()将负责不迭代hasOwnProperty()为false的项目。

jQuery.fn.extend({
    union: function(array1, array2) {
        var hash = {}, union = [];
        $.each($.merge($.merge([], array1), array2), function (index, value) { hash[value] = value; });
        $.each(hash, function (key, value) { union.push(key); } );
        return union;
    }
});

请注意,两个原始数组都保持不变。然后你这样称呼它:

var union = $.union(array1, array2);

答案 4 :(得分:9)

function unique(arrayName)
{
  var newArray=new Array();
  label: for(var i=0; i<arrayName.length;i++ )
  {  
    for(var j=0; j<newArray.length;j++ )
    {
      if(newArray[j]==arrayName[i]) 
        continue label;
    }
    newArray[newArray.length] = arrayName[i];
  }
  return newArray;
}

var arr1 = new Array(0,2,4,4,4,4,4,5,5,6,6,6,7,7,8,9,5,1,2,3,0);
var arr2= new Array(3,5,8,1,2,32,1,2,1,2,4,7,8,9,1,2,1,2,3,4,5);
var union = unique(arr1.concat(arr2));
console.log(union);

答案 5 :(得分:6)

我喜欢Peter Ajtai的独特解决方案,但代码不是很清楚。这是一个更好的选择:

function unique(x) {
  return x.filter(function(elem, index) { return x.indexOf(elem) === index; });
};
function union(x, y) {
  return unique(x.concat(y));
};

由于indexOf返回 first 出现的索引,我们会针对当前元素的索引(过滤谓词的第二个参数)进行检查。

答案 6 :(得分:6)

如果你想连接两个没有任何重复值的数组,试试这个

var a=[34, 35, 45, 48, 49];
var b=[48, 55];
var c=a.concat(b).sort();
var res=c.filter((value,pos) => {return c.indexOf(value) == pos;} );

答案 7 :(得分:6)

改编自:https://stackoverflow.com/a/4026828/1830259

Array.prototype.union = function(a) 
{
    var r = this.slice(0);
    a.forEach(function(i) { if (r.indexOf(i) < 0) r.push(i); });
    return r;
};

Array.prototype.diff = function(a)
{
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

var s1 = [1, 2, 3, 4];
var s2 = [3, 4, 5, 6];

console.log("s1: " + s1);
console.log("s2: " + s2);
console.log("s1.union(s2): " + s1.union(s2));
console.log("s2.union(s1): " + s2.union(s1));
console.log("s1.diff(s2): " + s1.diff(s2));
console.log("s2.diff(s1): " + s2.diff(s1));

// Output:
// s1: 1,2,3,4
// s2: 3,4,5,6
// s1.union(s2): 1,2,3,4,5,6
// s2.union(s1): 3,4,5,6,1,2
// s1.diff(s2): 1,2
// s2.diff(s1): 5,6 

答案 8 :(得分:3)

您可以使用jQuery插件:jQuery Array Utilities

例如下面的代码

$.union([1, 2, 2, 3], [2, 3, 4, 5, 5])

将返回[1,2,3,4,5]

答案 9 :(得分:2)

function unionArrays() {
    var args = arguments,
    l = args.length,
    obj = {},
    res = [],
    i, j, k;

    while (l--) {
        k = args[l];
        i = k.length;

        while (i--) {
            j = k[i];
            if (!obj[j]) {
                obj[j] = 1;
                res.push(j);
            }
        }   
    }

    return res;
}
var unionArr = unionArrays([34, 35, 45, 48, 49], [44, 55]);
console.log(unionArr);

与alejandro的方法有些相似,但稍微短一些,应该适用于任意数量的数组。

答案 10 :(得分:2)

function unionArray(arrayA, arrayB) {
  var obj = {},
      i = arrayA.length,
      j = arrayB.length,
      newArray = [];
  while (i--) {
    if (!(arrayA[i] in obj)) {
      obj[arrayA[i]] = true;
      newArray.push(arrayA[i]);
    }
  }
  while (j--) {
    if (!(arrayB[j] in obj)) {
      obj[arrayB[j]] = true;
      newArray.push(arrayB[j]);
    }
  }
  return newArray;
}
var unionArr = unionArray([34, 35, 45, 48, 49], [44, 55]);
console.log(unionArr);

更快 http://jsperf.com/union-array-faster

答案 11 :(得分:2)

function unite(arr1, arr2, arr3) {
 newArr=arr1.concat(arr2).concat(arr3);

 a=newArr.filter(function(value){
   return !arr1.some(function(value2){
      return value == value2;
   });
 });

console.log(arr1.concat(a));

}//This is for Sorted union following the order :)

答案 12 :(得分:2)

我首先连接数组,然后我只返回唯一值。

您必须创建自己的函数才能返回唯一值。由于它是一个有用的功能,你也可以add it in as a functionality of the Array

对于数组array1array2的情况,它看起来像这样:

  1. array1.concat(array2) - 连接两个数组
  2. array1.concat(array2).unique() - 仅返回唯一值。此处unique()是您添加到Array原型的方法。
  3. 整件事情看起来像这样:

    Array.prototype.unique = function () {
        var r = new Array();
        o: for(var i = 0, n = this.length; i < n; i++)
        {
            for(var x = 0, y = r.length; x < y; x++)
            {
                if(r[x]==this[i])
                {
                    continue o;
                }
            }
            r[r.length] = this[i];
        }
        return r;
    }
    var array1 = [34,35,45,48,49];
    var array2 = [34,35,45,48,49,55];
    
    // concatenate the arrays then return only the unique values
    console.log(array1.concat(array2).unique());

答案 13 :(得分:1)

之前刚刚写过同样的理由(适用于任意数量的数组):

/**
 * 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; }

答案 14 :(得分:1)

处理合并单个数组值的简单方法。

var values[0] = {"id":1235,"name":"value 1"}
values[1] = {"id":4323,"name":"value 2"}

var object=null;
var first=values[0];
for (var i in values) 
 if(i>0)    
 object= $.merge(values[i],first)

答案 15 :(得分:1)

你可以试试这些:

function union(a, b) {
    return a.concat(b).reduce(function(prev, cur) {
        if (prev.indexOf(cur) === -1) prev.push(cur);
        return prev;
    }, []);    
}

function union(a, b) {
    return a.concat(b.filter(function(el) {
        return a.indexOf(el) === -1;
    }));
}

答案 16 :(得分:1)

ES2015版

Array.prototype.diff = function(a) {return this.filter(i => a.indexOf(i) < 0)};

Array.prototype.union = function(a) {return [...this.diff(a), ...a]}

答案 17 :(得分:1)

kennytm答案的缩短版本:

function unionArrays(a, b) {
    const cache = {};

    a.forEach(item => cache[item] = item);
    b.forEach(item => cache[item] = item);

    return Object.keys(cache).map(key => cache[key]);
};

答案 18 :(得分:1)

如果您想要自定义等于功能来匹配您的元素,您可以在ES2015中使用此功能:

function unionEquals(left, right, equals){
    return left.concat(right).reduce( (acc,element) => {
        return acc.some(elt => equals(elt, element))? acc : acc.concat(element)
    }, []);
}

它遍历左+右阵列。然后,对于每个元素,如果它在累加器中没有找到该元素,则将填充累加器。最后,没有equals函数指定的重复。

漂亮,但可能对数千个对象效率不高。

答案 19 :(得分:0)

我认为最简单的方法是创建一个新数组,只添加indexOf确定的唯一值。

在我看来,这是最直接的解决方案,但我不知道它是否是最有效的。整理不会保留。

var a = [34, 35, 45, 48, 49],
    b = [48, 55];

var c = union(a, b);

function union(a, b) { // will work for n >= 2 inputs
    var newArray = [];

    //cycle through input arrays
    for (var i = 0, l = arguments.length; i < l; i++) {

        //cycle through each input arrays elements
        var array = arguments[i];
        for (var ii = 0, ll = array.length; ii < ll; ii++) {
            var val = array[ii];

            //only add elements to the new array if they are unique
            if (newArray.indexOf(val) < 0) newArray.push(val);
        }
    }
    return newArray;
}

答案 20 :(得分:0)

[i for( i of new Set(array1.concat(array2)))]

让我把它分成几部分

// This is a list by comprehension
// Store each result in an element of the array
[i
// will be placed in the variable "i", for each element of...
    for( i of
    // ... the Set which is made of...
            new Set(
                // ...the concatenation of both arrays
                array1.concat(array2)
            )
    )
]

换句话说,它首先连接两个,然后删除重复项(根据定义,Set不能重复)

请注意,在这种情况下,不保证元素的顺序。