[javascript] 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"));

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


답변

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 = function(arr2) { return this.filter(x => !arr2.includes(x)); }
[1, 2, 3].diff([2, 3])


답변

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"]

참고 indexOf 및 필터는 ie9 이전에는 사용할 수 없습니다.


답변

이것은 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]);


답변

일반 자바 스크립트

“차이”에 대한 두 가지 가능한 해석이 있습니다. 원하는 것을 고를 수 있도록하겠습니다. 당신이 가지고 있다고 :

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']( 또는 소위 대칭 차이 라는 둘 중 하나 a1 또는에 포함 된 모든 요소) 를 얻으려면 이 함수를 사용하십시오.a2

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