program story

JavaScript에서 두 배열의 차이를 얻는 방법은 무엇입니까?

inputbox 2020. 10. 2. 22:13
반응형

JavaScript에서 두 배열의 차이를 얻는 방법은 무엇입니까?


JavaScript에서 두 배열의 차이를 반환하는 방법이 있습니까?

예를 들면 :

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

// need ["c", "d"]

나는 당신이 정상적인 배열을 비교하고 있다고 가정합니다. 그렇지 않은 경우 for 루프를 for .. in 루프 로 변경해야합니다 .

function arr_diff (a1, a2) {

    var a = [], diff = [];

    for (var i = 0; i < a1.length; i++) {
        a[a1[i]] = true;
    }

    for (var i = 0; i < a2.length; i++) {
        if (a[a2[i]]) {
            delete a[a2[i]];
        } else {
            a[a2[i]] = true;
        }
    }

    for (var k in a) {
        diff.push(k);
    }

    return diff;
}

console.log(arr_diff(['a', 'b'], ['a', 'b', 'c', 'd']));
console.log(arr_diff("abcd", "abcde"));
console.log(arr_diff("zxc", "zxc"));

이전 버전과의 호환성에 관심이없는 경우 더 나은 솔루션은 필터를 사용하는 것입니다. 그러나 여전히이 솔루션이 작동합니다.


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

////////////////////  
// Examples  
////////////////////

[1,2,3,4,5,6].diff( [3,4,5] );  
// => [1, 2, 6]

["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);  
// => ["test5", "test6"]

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

////////////////////  
// Examples  
////////////////////

var dif1 = [1,2,3,4,5,6].diff( [3,4,5] );  
console.log(dif1); // => [1, 2, 6]


var dif2 = ["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);  
console.log(dif2); // => ["test5", "test6"]

참고 같이 IndexOf와 필터는 IE9 이전 IE에서 사용할 수 없습니다.


ES7을 사용하는 더 좋은 방법이 있습니다.

교차로

 let intersection = arr1.filter(x => arr2.includes(x));

교차점 차이 벤 다이어그램

들어 [1,2,3] [2,3]는 얻을 것입니다 [2,3]. 반면에 for [1,2,3] [2,3,5]는 같은 것을 반환합니다.

let difference = arr1.filter(x => !arr2.includes(x));

오른쪽 차이 벤 다이어그램

들어 [1,2,3] [2,3]는 얻을 것입니다 [1]. 반면에 for [1,2,3] [2,3,5]는 같은 것을 반환합니다.

A에 대한 대칭 적 차이 , 당신은 할 수 있습니다 :

let difference = arr1
                 .filter(x => !arr2.includes(x))
                 .concat(arr2.filter(x => !arr1.includes(x)));

대칭 차이 벤 다이어그램

이렇게하면 arr2에없는 arr1의 모든 요소를 ​​포함하는 배열을 얻을 수 있으며 그 반대의 경우도 마찬가지입니다.

@Joshaven Potter가 그의 대답에 대해 지적했듯이 이것을 Array.prototype에 추가하여 다음과 같이 사용할 수 있습니다.

Array.prototype.diff = arr1.filter(x => arr2.includes(x));
[1, 2, 3].diff([2, 3])

이것은 jQuery를 사용하여 원하는 결과를 정확하게 얻는 가장 쉬운 방법입니다.

var diff = $(old_array).not(new_array).get();

diff이제는 안에 old_array없었던 것을 포함합니다 .new_array


Underscore (또는 드롭 인 대체 Lo-Dash ) 의 차이 방법 도이 작업을 수행 할 수 있습니다.

(R)eturns the values from array that are not present in the other arrays

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

Underscore 함수와 마찬가지로보다 객체 지향적 인 스타일로 사용할 수도 있습니다.

_([1, 2, 3, 4, 5]).difference([5, 2, 10]);

일반 JavaScript

"차이"에 대해 두 가지 가능한 해석이 있습니다. 원하는 것을 선택해 드리겠습니다. 당신이 가지고 있다고 :

var a1 = ['a', 'b'     ];
var a2 = [     'b', 'c'];
  1. 을 얻으려면 ['a']다음 함수를 사용하십시오.

    function difference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      return result;
    }
    
  2. ['a', 'c']( 또는 중 하나에 포함 된 모든 요소 -소위 대칭 차이 ) 를 얻으려면 다음 함수를 사용하십시오.a1a2

    function symmetricDifference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      for (i = 0; i < a2.length; i++) {
        if (a1.indexOf(a2[i]) === -1) {
          result.push(a2[i]);
        }
      }
      return result;
    }
    

Lodash / 밑줄

lodash를 사용하는 _.difference(a1, a2)경우 (위의 케이스 1) 또는 _.xor(a1, a2)(케이스 2)를 사용할 수 있습니다 .

Underscore.js를 사용하는 _.difference(a1, a2)경우 사례 1 함수를 사용할 수 있습니다 .

매우 큰 어레 이용 ES6 세트

위의 코드는 모든 브라우저에서 작동합니다. 그러나 약 10,000 개 이상의 항목이있는 대규모 배열의 경우 O (n²) 복잡성이 있기 때문에 상당히 느려집니다. 많은 최신 브라우저에서 ES6 Set개체를 활용 하여 작업 속도를 높일 수 있습니다. Lodash는 사용 Set가능할 때 자동으로 사용 합니다. lodash를 사용하지 않는 경우 Axel Rauschmayer의 블로그 게시물 에서 영감을 얻은 다음 구현을 사용하십시오 .

function difference(a1, a2) {
  var a2Set = new Set(a2);
  return a1.filter(function(x) { return !a2Set.has(x); });
}

function symmetricDifference(a1, a2) {
  return difference(a1, a2).concat(difference(a2, a1));
}

메모

-0, +0, NaN 또는 희소 배열에 관심이 있다면 모든 예의 동작이 놀랍거나 명확하지 않을 수 있습니다. (대부분의 경우 이것은 중요하지 않습니다.)


대칭적인 차이 를 얻으려면 두 가지 방법으로 (또는 여러 배열의 경우 모든 방법으로) 배열을 비교해야합니다.

여기에 이미지 설명 입력


ES7 (ECMAScript 2016)

// diff between just two arrays:
function arrayDiff(a, b) {
    return [
        ...a.filter(x => !b.includes(x)),
        ...b.filter(x => !a.includes(x))
    ];
}

// diff between multiple arrays:
function arrayDiff(...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter(x => !unique.includes(x));
    }));
}

ES6 (ECMAScript 2015)

// diff between just two arrays:
function arrayDiff(a, b) {
    return [
        ...a.filter(x => b.indexOf(x) === -1),
        ...b.filter(x => a.indexOf(x) === -1)
    ];
}

// diff between multiple arrays:
function arrayDiff(...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter(x => unique.indexOf(x) === -1);
    }));
}

ES5 (ECMAScript 5.1)

// diff between just two arrays:
function arrayDiff(a, b) {
    var arrays = Array.prototype.slice.call(arguments);
    var diff = [];

    arrays.forEach(function(arr, i) {
        var other = i === 1 ? a : b;
        arr.forEach(function(x) {
            if (other.indexOf(x) === -1) {
                diff.push(x);
            }
        });
    })

    return diff;
}

// diff between multiple arrays:
function arrayDiff() {
    var arrays = Array.prototype.slice.call(arguments);
    var diff = [];

    arrays.forEach(function(arr, i) {
        var others = arrays.slice(0);
        others.splice(i, 1);
        var otherValues = Array.prototype.concat.apply([], others);
        var unique = otherValues.filter(function (x, j) { 
            return otherValues.indexOf(x) === j; 
        });
        diff = diff.concat(arr.filter(x => unique.indexOf(x) === -1));
    });
    return diff;
}

예:

// diff between two arrays:
const a = ['a', 'd', 'e'];
const b = ['a', 'b', 'c', 'd'];
arrayDiff(a, b); // (3) ["e", "b", "c"]

// diff between multiple arrays
const a = ['b', 'c', 'd', 'e', 'g'];
const b = ['a', 'b'];
const c = ['a', 'e', 'f'];
arrayDiff(a, b, c); // (4) ["c", "d", "g", "f"]

객체 배열의 차이점

function arrayDiffByKey(key, ...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter( x =>
            !unique.some(y => x[key] === y[key])
        );
    }));
}

예:

const a = [{k:1}, {k:2}, {k:3}];
const b = [{k:1}, {k:4}, {k:5}, {k:6}];
const c = [{k:3}, {k:5}, {k:7}];
arrayDiffByKey('k', a, b, c); // (4) [{k:2}, {k:4}, {k:6}, {k:7}]

이 경우 세트사용할 수 있습니다 . 이러한 종류의 작업 (연합, 교차, 차이)에 최적화되어 있습니다.

중복을 허용하지 않으면 귀하의 사례에 적용되는지 확인하십시오.

var a = new JS.Set([1,2,3,4,5,6,7,8,9]);
var b = new JS.Set([2,4,6,8]);

a.difference(b)
// -> Set{1,3,5,7,9}

function diff(a1, a2) {
  return a1.concat(a2).filter(function(val, index, arr){
    return arr.indexOf(val) === arr.lastIndexOf(val);
  });
}

두 배열을 병합하면 고유 값이 한 번만 표시되므로 indexOf ()는 lastIndexOf ()와 동일합니다.


한 배열에서 다른 배열을 빼려면 아래 스 니펫을 사용하면됩니다.

var a1 = ['1','2','3','4','6'];
var a2 = ['3','4','5'];

var items = new Array();

items = jQuery.grep(a1,function (item) {
    return jQuery.inArray(item, a2) < 0;
});

두 번째 배열에는 존재하지 않는 첫 번째 배열의 항목 인 [ '1,'2 ','6 ']를 반환합니다.

따라서 문제 샘플에 따르면 다음 코드가 정확한 솔루션입니다.

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var _array = new Array();

_array = jQuery.grep(array2, function (item) {
     return jQuery.inArray(item, array1) < 0;
});

사용하는 솔루션 indexOf()은 작은 어레이에 적합하지만 길이가 길어짐에 따라 알고리즘의 성능에 접근 O(n^2)합니다. 다음은 객체를 연관 배열로 사용하여 배열 항목을 키로 저장함으로써 매우 큰 배열에 대해 더 나은 성능을 발휘하는 솔루션입니다. 또한 중복 항목을 자동으로 제거하지만 문자열 값 (또는 문자열로 안전하게 저장할 수있는 값)으로 만 작동합니다.

function arrayDiff(a1, a2) {
  var o1={}, o2={}, diff=[], i, len, k;
  for (i=0, len=a1.length; i<len; i++) { o1[a1[i]] = true; }
  for (i=0, len=a2.length; i<len; i++) { o2[a2[i]] = true; }
  for (k in o1) { if (!(k in o2)) { diff.push(k); } }
  for (k in o2) { if (!(k in o1)) { diff.push(k); } }
  return diff;
}

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
arrayDiff(a1, a2); // => ['c', 'd']
arrayDiff(a2, a1); // => ['c', 'd']

세트 및 표시 연산자가있는 ES6 (Firefox에서만 작동 할 때 호환성 표 확인 ) 이 도착 하면 다음 한 줄을 작성할 수 있습니다.

var a = ['a', 'b', 'c', 'd'];
var b = ['a', 'b'];
var b1 = new Set(b);
var difference = [...new Set([...a].filter(x => !b1.has(x)))];

결과는 [ "c", "d" ].


ES2015를 사용한 기능적 접근 방식

difference두 배열 사이의 계산은 Set작업 중 하나입니다 . 이 용어는 이미 Set조회 속도를 높이기 위해 기본 유형을 사용해야 함을 나타냅니다 . 어쨌든 두 세트의 차이를 계산할 때 세 가지 순열이 있습니다.

[+left difference] [-intersection] [-right difference]
[-left difference] [-intersection] [+right difference]
[+left difference] [-intersection] [+right difference]

다음은 이러한 순열을 반영하는 기능적 솔루션입니다.

왼쪽 difference:

// small, reusable auxiliary functions

const apply = f => x => f(x);
const flip = f => y => x => f(x) (y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// left difference

const differencel = xs => ys => {
  const zs = createSet(ys);
  return filter(x => zs.has(x)
     ? false
     : true
  ) (xs);
};


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];


// run the computation

console.log( differencel(xs) (ys) );

오른쪽 difference:

differencer사소합니다. 그것은 단지 differencel뒤집힌 주장입니다. 편의를 위해 함수를 작성할 수 있습니다 const differencer = flip(differencel).. 그게 다야!

대칭 difference:

이제 왼쪽과 오른쪽이 있으므로 대칭을 구현하는 것도 difference간단합니다.

// small, reusable auxiliary functions

const apply = f => x => f(x);
const flip = f => y => x => f(x) (y);
const concat = y => xs => xs.concat(y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// left difference

const differencel = xs => ys => {
  const zs = createSet(ys);
  return filter(x => zs.has(x)
     ? false
     : true
  ) (xs);
};


// symmetric difference

const difference = ys => xs =>
 concat(differencel(xs) (ys)) (flip(differencel) (xs) (ys));

// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];


// run the computation

console.log( difference(xs) (ys) );

이 예제는 함수형 프로그래밍이 의미하는 바에 대한 인상을 얻기위한 좋은 출발점이라고 생각합니다.

여러 가지 방법으로 함께 연결할 수있는 빌딩 블록을 사용한 프로그래밍.


Joshaven Potter의 위 답변은 훌륭합니다. 그러나 그것은 배열 C에 있지 않은 배열 B의 요소를 반환하지만 그 반대는 아닙니다. 예를 들어, 그렇다면 var a=[1,2,3,4,5,6].diff( [3,4,5,7]);다음과 같이 출력됩니다. ==> [1,2,6], 그러나 두 가지의 실제 차이는 아닙니다 [1,2,6,7] . 위의 Potter의 코드를 계속 사용할 수 있지만 단순히 비교를 한 번 뒤로 다시 실행하면됩니다.

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return !(a.indexOf(i) > -1);});
};

////////////////////  
// Examples  
////////////////////

var a=[1,2,3,4,5,6].diff( [3,4,5,7]);
var b=[3,4,5,7].diff([1,2,3,4,5,6]);
var c=a.concat(b);
console.log(c);

다음과 같이 출력되어야합니다. [ 1, 2, 6, 7 ]


문제를 해결하는 또 다른 방법

function diffArray(arr1, arr2) {
    return arr1.concat(arr2).filter(function (val) {
        if (!(arr1.includes(val) && arr2.includes(val)))
            return val;
    });
}

diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]);    // return [7, 4, 5]

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

eg:- 

[1,2,3,4,5,6,7].difference( [3,4,5] );  
 => [1, 2, 6 , 7]

이것은 어떤가요:

Array.prototype.contains = function(needle){
  for (var i=0; i<this.length; i++)
    if (this[i] == needle) return true;

  return false;
} 

Array.prototype.diff = function(compare) {
    return this.filter(function(elem) {return !compare.contains(elem);})
}

var a = new Array(1,4,7, 9);
var b = new Array(4, 8, 7);
alert(a.diff(b));

따라서이 방법으로 array1.diff(array2)차이를 얻을 수 있습니다 (알고리즘에 대한 끔찍한 시간 복잡성-O (array1.length x array2.length) 나는 믿습니다)


JavaScript의 필터 기능을 사용한 매우 간단한 솔루션 :

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

function diffArray(arr1, arr2) {
  var newArr = [];
  var myArr = arr1.concat(arr2);
  
    newArr = myArr.filter(function(item){
      return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0;
    });
   alert(newArr);
}

diffArray(a1, a2);


http://phrogz.net/JS/ArraySetMath.js사용하여 다음을 수행 할 수 있습니다.

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var array3 = array2.subtract( array1 );
// ["test5", "test6"]

var array4 = array1.exclusion( array2 );
// ["test5", "test6"]

function diffArray(arr1, arr2) {
  var newArr = arr1.concat(arr2);
  return newArr.filter(function(i){
    return newArr.indexOf(i) == newArr.lastIndexOf(i);
  });
}

이것은 나를 위해 일합니다


  • 순수 JavaScript 솔루션 (라이브러리 없음)
  • 이전 브라우저와 호환 가능 (을 사용하지 않음 filter)
  • O (n ^ 2)
  • fn배열 항목을 비교하는 방법을 지정할 수있는 선택적 콜백 매개 변수

function diff(a, b, fn){
    var max = Math.max(a.length, b.length);
        d = [];
    fn = typeof fn === 'function' ? fn : false
    for(var i=0; i < max; i++){
        var ac = i < a.length ? a[i] : undefined
            bc = i < b.length ? b[i] : undefined;
        for(var k=0; k < max; k++){
            ac = ac === undefined || (k < b.length && (fn ? fn(ac, b[k]) : ac == b[k])) ? undefined : ac;
            bc = bc === undefined || (k < a.length && (fn ? fn(bc, a[k]) : bc == a[k])) ? undefined : bc;
            if(ac == undefined && bc == undefined) break;
        }
        ac !== undefined && d.push(ac);
        bc !== undefined && d.push(bc);
    }
    return d;
}

alert(
    "Test 1: " + 
    diff(
        [1, 2, 3, 4],
        [1, 4, 5, 6, 7]
      ).join(', ') +
    "\nTest 2: " +
    diff(
        [{id:'a',toString:function(){return this.id}},{id:'b',toString:function(){return this.id}},{id:'c',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        [{id:'a',toString:function(){return this.id}},{id:'e',toString:function(){return this.id}},{id:'f',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        function(a, b){ return a.id == b.id; }
    ).join(', ')
);


이것은 작동합니다 : 기본적으로 두 배열을 병합하고 중복을 찾고 복제되지 않은 것을 새로운 배열로 밀어 넣습니다.

function diff(arr1, arr2) {
  var newArr = [];
  var arr = arr1.concat(arr2);
  
  for (var i in arr){
    var f = arr[i];
    var t = 0;
    for (j=0; j<arr.length; j++){
      if(arr[j] === f){
        t++; 
        }
    }
    if (t === 1){
      newArr.push(f);
        }
  } 
  return newArr;
}


그냥 생각하면 ... 도전을 위해 ;-)이게 작동할까요 ... (문자열, 숫자 등의 기본 배열에 대해) 중첩 된 배열 없음

function diffArrays(arr1, arr2, returnUnion){
  var ret = [];
  var test = {};
  var bigArray, smallArray, key;
  if(arr1.length >= arr2.length){
    bigArray = arr1;
    smallArray = arr2;
  } else {
    bigArray = arr2;
    smallArray = arr1;
  }
  for(var i=0;i<bigArray.length;i++){
    key = bigArray[i];
    test[key] = true;
  }
  if(!returnUnion){
    //diffing
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = null;
      }
    }
  } else {
    //union
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = true;
      }
    }
  }
  for(var i in test){
    ret.push(i);
  }
  return ret;
}

array1 = "test1", "test2","test3", "test4", "test7"
array2 = "test1", "test2","test3","test4", "test5", "test6"
diffArray = diffArrays(array1, array2);
//returns ["test5","test6","test7"]

diffArray = diffArrays(array1, array2, true);
//returns ["test1", "test2","test3","test4", "test5", "test6","test7"]

정렬은 위에서 언급 한 것과 같지 않을 수 있지만 원하는 경우 배열에서 .sort ()를 호출하여 정렬합니다.


이전 배열과 새 배열을 가져 와서 추가 된 항목 배열과 제거 된 항목 배열을 제공하는 유사한 함수를 원했고 효율적이기를 원했습니다 (.contains 없음!).

여기에서 제안한 솔루션을 사용할 수 있습니다. http://jsbin.com/osewu3/12 .

누구든지 해당 알고리즘에 대한 문제 / 개선 사항을 볼 수 있습니까? 감사!

코드 목록 :

function diff(o, n) {
  // deal with empty lists
  if (o == undefined) o = [];
  if (n == undefined) n = [];

  // sort both arrays (or this won't work)
  o.sort(); n.sort();

  // don't compare if either list is empty
  if (o.length == 0 || n.length == 0) return {added: n, removed: o};

  // declare temporary variables
  var op = 0; var np = 0;
  var a = []; var r = [];

  // compare arrays and add to add or remove lists
  while (op < o.length && np < n.length) {
      if (o[op] < n[np]) {
          // push to diff?
          r.push(o[op]);
          op++;
      }
      else if (o[op] > n[np]) {
          // push to diff?
          a.push(n[np]);
          np++;
      }
      else {
          op++;np++;
      }
  }

  // add remaining items
  if( np < n.length )
    a = a.concat(n.slice(np, n.length));
  if( op < o.length )
    r = r.concat(o.slice(op, o.length));

  return {added: a, removed: r}; 
}

최고의 답변을위한 작은 수정

function arr_diff(a1, a2)
{
  var a=[], diff=[];
  for(var i=0;i<a1.length;i++)
    a[a1[i]]=a1[i];
  for(var i=0;i<a2.length;i++)
    if(a[a2[i]]) delete a[a2[i]];
    else a[a2[i]]=a2[i];
  for(var k in a)
   diff.push(a[k]);
  return diff;
}

현재 유형의 요소를 고려합니다. b / c a [a1 [i]]를 만들면 원래 값에서 문자열로 값을 변환하므로 실제 값을 잃었습니다.


underscore.js를 사용할 수 있습니다 : http://underscorejs.org/#intersection

배열에 필요한 방법이 있습니다.

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]

이것은 Thinker가 받아 들여진 대답에서 영감을 얻었지만 Thinker의 대답은 배열이 세트라고 가정하는 것 같습니다. 배열이 [ "1", "2" ]있고[ "1", "1", "2", "2" ]

이러한 배열의 차이점은 [ "1", "2" ]. 다음 솔루션은 O (n * n)이므로 이상적이지는 않지만 큰 어레이가 있으면 Thinker 솔루션보다 메모리 이점도 있습니다.

처음부터 세트를 다루는 경우 Thinker의 솔루션이 확실히 더 좋습니다. 필터에 액세스 할 수있는 최신 버전의 Javascript가있는 경우에도이를 사용해야합니다. 이것은 집합을 다루지 않고 (어떤 이유로 든) 이전 버전의 JavaScript를 사용하는 사람들만을위한 것입니다.

if (!Array.prototype.diff) { 
    Array.prototype.diff = function (array) {
        // if the other array is a falsy value, return a copy of this array
        if ((!array) || (!Array.prototype.isPrototypeOf(array))) { 
            return this.slice(0);
        }

        var diff = [];
        var original = this.slice(0);

        for(var i=0; i < array.length; ++i) {
            var index = original.indexOf(array[i]);
            if (index > -1) { 
                original.splice(index, 1);
            } else { 
                diff.push(array[i]);
            }
        }

        for (var i=0; i < original.length; ++i) {
            diff.push(original[i]);
        }
        return diff;
    }
}   

단순히 모든 값을 비교하고 반복되지 않는 값으로 배열을 반환합니다.

var main = [9, '$', 'x', 'r', 3, 'A', '#', 0, 1];

var arr0 = ['Z', 9, 'e', '$', 'r'];
var arr1 = ['x', 'r', 3, 'A', '#'];
var arr2 = ['m', '#', 'a', 0, 'r'];
var arr3 = ['$', 1, 'n', '!', 'A'];


Array.prototype.diff = function(arrays) {
    var items = [].concat.apply(this, arguments);
    var diff = [].slice.call(items), i, l, x, pos;

    // go through all items
    for (x = 0, i = 0, l = items.length; i < l; x = 0, i++) {
        // find all positions
        while ((pos = diff.indexOf(items[i])) > -1) {
            // remove item + increase found count
            diff.splice(pos, 1) && x++;
        }
        // if item was found just once, put it back
        if (x === 1) diff.push(items[i]);
    }
    // get all not duplicated items
    return diff;
};

main.diff(arr0, arr1, arr2, arr3).join(''); // returns "Zeman!"

[].diff(main, arr0, arr1, arr2, arr3).join(''); // returns "Zeman!"

function diff(arr1, arr2) {
  var filteredArr1 = arr1.filter(function(ele) {
    return arr2.indexOf(ele) == -1;
  });

  var filteredArr2 = arr2.filter(function(ele) {
    return arr1.indexOf(ele) == -1;
  });
  return filteredArr1.concat(filteredArr2);
}

diff([1, "calf", 3, "piglet"], [1, "calf", 3, 4]); // Log ["piglet",4]

// es6 접근

function diff(a, b) {
  var u = a.slice(); //dup the array
  b.map(e => {
    if (u.indexOf(e) > -1) delete u[u.indexOf(e)]
    else u.push(e)   //add non existing item to temp array
  })
  return u.filter((x) => {return (x != null)}) //flatten result
}

참고 URL : https://stackoverflow.com/questions/1187518/how-to-get-the-difference-between-two-arrays-in-javascript

반응형