[javascript] 두 배열의 값이 동일한 지 확인하는 방법

이 두 배열이 있습니다. 하나는 ajax 요청의 정보로 채워지고 다른 하나는 사용자가 클릭하는 버튼을 저장합니다. 이 코드를 사용합니다 (샘플 번호로 채웠습니다).

var array1 = [2, 4];
var array2 = [4, 2]; //It cames from the user button clicks, so it might be disordered.
array1.sort(); //Sorts both Ajax and user info.
array2.sort();
if (array1==array2) {
    doSomething();
}else{
    doAnotherThing();
}

그러나 false두 배열이 동일하지만 이름이 다른 경우에도 항상을 제공합니다 . (Chrome의 JS 콘솔에서 확인했습니다). 그래서,이 두 배열이 같은 것을 포함하는지 알 수있는 방법이 있습니까? 왜 주는가 false? 첫 번째 배열의 어떤 값이 두 번째 배열에 없는지 어떻게 알 수 있습니까?



답변

function arraysEqual(_arr1, _arr2) {

    if (!Array.isArray(_arr1) || ! Array.isArray(_arr2) || _arr1.length !== _arr2.length)
      return false;

    var arr1 = _arr1.concat().sort();
    var arr2 = _arr2.concat().sort();

    for (var i = 0; i < arr1.length; i++) {

        if (arr1[i] !== arr2[i])
            return false;

    }

    return true;

}

이것은 이전 답변과 달리 원래 배열을 수정하지 않습니다.


답변

배열 항목이 객체가 아닌 경우 (예 : 숫자 또는 문자열 인 경우) 결합 된 문자열을 비교하여 순서에 상관없이 동일한 멤버가 있는지 확인할 수 있습니다.

var array1= [10, 6, 19, 16, 14, 15, 2, 9, 5, 3, 4, 13, 8, 7, 1, 12, 18, 11, 20, 17];
var array2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17];

if(array1.sort().join(',')=== array2.sort().join(',')){
    alert('same members');
}
else alert('not a match');


답변

두 배열이 동일한 값 (각 값의 발생 횟수 및 순서에 관계없이)을 갖는 경우에만 확인하려면 lodash 를 사용하여 수행 할 수 있습니다 .

_.isEmpty(_.xor(array1, array2))

짧고 간단하고 예쁘다!


답변

Array.prototype.compare = function(testArr) {
    if (this.length != testArr.length) return false;
    for (var i = 0; i < testArr.length; i++) {
        if (this[i].compare) { //To test values in nested arrays
            if (!this[i].compare(testArr[i])) return false;
        }
        else if (this[i] !== testArr[i]) return false;
    }
    return true;
}

var array1 = [2, 4];
var array2 = [4, 2];
if(array1.sort().compare(array2.sort())) {
    doSomething();
} else {
    doAnotherThing();
}

아마도?


답변

코드가 작동하지 않는 이유

JavaScript에는 원시 데이터 유형 과 비 원시 데이터 유형이 있습니다.

기본 데이터 타입의 경우 =====체크 바의 양쪽에있는 것들과 동일한 값을 가져야하는지 여부. 그것이 1 === 1사실입니다.

배열 ==과 같은 원시 데이터 유형이 아닌 ===경우 참조 동등성을 확인하십시오. 즉 그들은 여부를 확인한다 arr1arr2같은 객체입니다. 귀하의 예에서 두 배열은 동일한 순서로 동일한 객체를 갖지만 동일하지는 않습니다.

솔루션

두 배열 arr1arr2은 다음과 같은 경우에만 동일한 멤버를 갖습니다.

  • 모든 것이 들어 arr2있습니다.arr1

  • 모든 것이 들어 arr1있습니다.arr2

그래서 이것은 트릭을 할 것입니다 (ES2016) :

const containsAll = (arr1, arr2) =>
                arr2.every(arr2Item => arr1.includes(arr2Item))

const sameMembers = (arr1, arr2) =>
                        containsAll(arr1, arr2) && containsAll(arr2, arr1);

sameMembers(arr1, arr2); // `true`

Underscore를 사용하는이 두 번째 솔루션 은 수행하려는 작업에 더 가깝습니다.

arr1.sort();
arr2.sort();

_.isEqual(arr1, arr2); // `true`

isEqual“깊은 평등”을 확인하기 때문에 작동 합니다. 즉, 참조 평등 이상을보고 값을 비교합니다.

세 번째 질문에 대한 해결책

또한에 arr1포함되지 않은 항목을 찾는 방법을 물었 습니다 arr2.

이렇게하면됩니다 (ES2015).

const arr1 = [1, 2, 3, 4];
const arr2 = [3, 2, 1];

arr1.filter(arr1Item => !arr2.includes(arr1Item)); // `[4]`

Underscore의 difference: 메소드를 사용할 수도 있습니다 .

_.difference(arr1, arr2); // `[4]`

최신 정보

@Redu의 의견을 참조하십시오. 내 솔루션은에 대한 sameMembers것이지만 염두에 두어야 할 것은으로 sameMembersInOrder도 알려져 있습니다 deepEquals.

업데이트 2

배열 멤버의 순서에 신경 쓰지 않는다면 ES2015 + SetArray. 위험한 원숭이 패치 를 구현 isSuperset하고difference 사용 하는 방법에 대한 MDN 노트를 참조하십시오 .


답변

객체 동등성 검사 :JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())

위의 테스트는 http://www.w3schools.com/jsref/jsref_sort.asp에 설명 된대로 정렬 기능을 사용하는 경우 객체 배열에서도 작동합니다 .

플랫 JSON 스키마가있는 작은 배열에 충분할 수 있습니다.


답변

우리의 목표는 기본적으로 2 개의 배열이 동일한 집합인지 확인하는 것입니다. 집합 은 수학적으로 정의 된 집합 입니다. 가장 빠른 정렬은 점근 적으로 O (nlog (n)) 시간이 걸립니다. 따라서 배열을 정렬하면 최소한 O (nlog (n)) 시간이 걸립니다. 그러나이 작업을 더 빠르게 수행 있으며, 사전 데이터 구조에서 점근 적으로 O (n) 시간 (최악의 경우가 아닌 평균 사례 ) 이 걸립니다 . JS에서 사전은 단순히 키와 값이있는 객체입니다.

/** assumes array elements are primitive types
* check whether 2 arrays are equal sets.
* @param  {} a1 is an array
* @param  {} a2 is an array
*/
function areArraysEqualSets(a1, a2) {
  const superSet = {};
  for (const i of a1) {
    const e = i + typeof i;
    superSet[e] = 1;
  }

  for (const i of a2) {
    const e = i + typeof i;
    if (!superSet[e]) {
      return false;
    }
    superSet[e] = 2;
  }

  for (let e in superSet) {
    if (superSet[e] === 1) {
      return false;
    }
  }

  return true;
}

이 기능은 원시 형의 배열로 작동하고 가정합니다 a1a2배열입니다.