Development Tip

JavaScript에서 두 배열의 합집합 얻기

yourdevel 2020. 11. 25. 21:18
반응형

JavaScript에서 두 배열의 합집합 얻기


이 질문에 이미 답변이 있습니다.

의 배열 [34, 35, 45, 48, 49]과 다른 배열이 있다고 가정 [48, 55]합니다. 결과 배열을 [34, 35, 45, 48, 49, 55]어떻게 얻을 수 있습니까?


당신은 순서를 유지하고 고려해야 할 필요가없는 경우 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]));


세트 및 표시 연산자가 포함 된 ES6 (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]그것을 배열로 다시 변환합니다.


라이브러리 밑줄 을 사용하면 다음 과 같이 작성할 수 있습니다.

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


나는 아마 여기서 죽은 스레드에 시간을 낭비하고있을 것입니다. 나는 이것을 구현해야했고 내가 시간을 낭비하고 있는지 알아보기 위해 갔다.

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);

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);


출처 : 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 

중복 값없이 두 배열을 연결하려면 다음을 시도하십시오.

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;} );

나는 Peter Ajtai의 concat-then-unique 솔루션을 좋아하지만 코드는 명확하지 않습니다. 더 좋은 대안이 있습니다.

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

indexOf는 첫 번째 발생 의 인덱스를 반환하므로 현재 요소의 인덱스 (필터 조건 자에 대한 두 번째 매개 변수)와 비교하여이를 확인합니다.


jQuery 플러그인을 사용할 수 있습니다 : jQuery Array Utilities

예를 들어 아래 코드

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

[1,2,3,4,5]를 반환합니다.


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 :)

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]);
};

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의 방법과 다소 유사하지만 조금 더 짧으며 여러 배열에서 작동해야합니다.


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


먼저 배열을 연결 한 다음 고유 한 값만 반환합니다.

고유 한 값을 반환하려면 고유 한 함수를 만들어야합니다. 이 유용한 기능이기 때문에, 당신은뿐만 아니라 수 의 기능성으로의 추가Array .

배열과 함께 귀하의 경우 array1array2는 같을 것이다 :

  1. array1.concat(array2) -두 배열 연결
  2. array1.concat(array2).unique()-고유 한 값만 반환합니다. unique()에 대한 프로토 타입에 추가 한 메서드는 다음과 같습니다 Array.

전체 내용은 다음과 같습니다.

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());


같은 이유로 이전에 썼습니다 (모든 양의 배열에서 작동) :

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

단일 배열 값 병합을 처리하는 간단한 방법입니다.

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)

다음을 시도해 볼 수 있습니다.

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;
    }));
}

ES2015 버전

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

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

당신이 원하는 경우 사용자가 동일 하여 요소에 맞게 기능을, 당신은 ES2015에서이 기능을 사용할 수 있습니다 :

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

It traverses the left+right array. Then for each element, will fill the accumulator if it does not find that element in the accumulator. At the end, there are no duplicate as specified by the equals function.

Pretty, but probably not very efficient with thousands of objects.


I think it would be simplest to create a new array, adding the unique values only as determined by indexOf.

This seems to me to be the most straightforward solution, though I don't know if it is the most efficient. Collation is not preserved.

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

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

Let me break this into parts for you

// 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)
            )
    )
]

In other words, it first concatenates both and then it removes the duplicates (a Set, by definition cannot have duplicates)

Do note, though, that the order of the elements is not guaranteed, in this case.

참고URL : https://stackoverflow.com/questions/3629817/getting-a-union-of-two-arrays-in-javascript

반응형