JavaScript에서 배열을 비교하는 방법은 무엇입니까?


988

두 배열을 이상적으로 효율적으로 비교하고 싶습니다. true그들이 동일하고 false그렇지 않다면 공상 이 아닙니다. 당연히 비교 연산자가 작동하지 않는 것 같습니다.

var a1 = [1,2,3];
var a2 = [1,2,3];
console.log(a1==a2);    // Returns false
console.log(JSON.stringify(a1)==JSON.stringify(a2));    // Returns true

각 배열의 JSON 인코딩은 각 값을 반복하지 않고 배열을 간단히 비교하는 더 빠르고 "더 나은"방법이 있습니까?


5
먼저 길이와 각 값이 같은지 비교할 수 있습니다.
TJHeuvel

55
두 배열이 당신에게 똑같은 이유는 무엇입니까? 같은 요소? 요소의 동일한 순서? JSON으로 인코딩하면 배열의 요소를 JSON으로 직렬화 할 수있는 경우에만 작동합니다. 배열에 객체가 포함될 수 있다면 얼마나 깊이 갈 것입니까? 두 개체가 "동일한"시기는 언제입니까?
Felix Kling

48
"평등"을 정의하는 @FelixKling은 분명 미묘한 주제이지만 고급 언어에서 JavaScript를 사용하는 사람들에게는과 같은 어설프게 변명의 여지가 없습니다 ([] == []) == false.
Alex D

4
@ AlexD 배열이 참조 평등을 사용하는 것처럼 보입니다. 당신이 그렇게 할 수 없다면 그것은 매우
끔찍할

3
@ AlexD 나는 이것이 일어나지 않는 언어를 다소 생각할 수 없습니다. C ++에서는 두 포인터를 비교합니다-거짓. Java에서는 javascript와 동일한 작업을 수행합니다. PHP에서는 배후에서 무언가가 배열을 반복합니다. PHP를 고급 언어라고 부릅니까?
Tomáš Zato-복원 Monica Monica

답변:


877

배열을 비교하려면 배열을 반복하고 모든 값을 비교하십시오.

배열 비교 :

// Warn if overriding existing method
if(Array.prototype.equals)
    console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
    // if the other array is a falsy value, return
    if (!array)
        return false;

    // compare lengths - can save a lot of time 
    if (this.length != array.length)
        return false;

    for (var i = 0, l=this.length; i < l; i++) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].equals(array[i]))
                return false;       
        }           
        else if (this[i] != array[i]) { 
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;   
        }           
    }       
    return true;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});

용법:

[1, 2, [3, 4]].equals([1, 2, [3, 2]]) === false;
[1, "2,3"].equals([1, 2, 3]) === false;
[1, 2, [3, 4]].equals([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].equals([1, 2, 1, 2]) === true;

" 하지만 문자열을 비교하는 것이 훨씬 빠릅니다. 루프가 없습니다 ... " 라고 말하면 루프 가 있다는 것을 알아야합니다. 첫 번째 재귀 루프는 Array를 문자열로 변환하고 두 번째는 두 문자열을 비교합니다. 이 방법은 은 string 사용보다 빠릅니다 .

더 많은 양의 데이터는 항상 객체가 아닌 배열에 저장해야한다고 생각합니다. 그러나 개체를 사용하면 부분적으로 비교할 수도 있습니다.
방법은 다음과 같습니다.

객체 비교 :

위에서 언급했듯이 두 개의 객체 인스턴스 는 현재 동일한 데이터를 포함하더라도 결코 같지 않습니다.

({a:1, foo:"bar", numberOfTheBeast: 666}) == ({a:1, foo:"bar", numberOfTheBeast: 666})  //false

예를 들어 객체 내에 개인 변수 가있을 수 있기 때문 입니다.

그러나 객체 구조를 사용하여 데이터를 포함하는 경우 비교는 여전히 가능합니다.

Object.prototype.equals = function(object2) {
    //For the first loop, we only check for types
    for (propName in this) {
        //Check for inherited methods and properties - like .equals itself
        //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
        //Return false if the return value is different
        if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
            return false;
        }
        //Check instance type
        else if (typeof this[propName] != typeof object2[propName]) {
            //Different types => not equal
            return false;
        }
    }
    //Now a deeper check using other objects property names
    for(propName in object2) {
        //We must check instances anyway, there may be a property that only exists in object2
            //I wonder, if remembering the checked values from the first loop would be faster or not 
        if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
            return false;
        }
        else if (typeof this[propName] != typeof object2[propName]) {
            return false;
        }
        //If the property is inherited, do not check any more (it must be equa if both objects inherit it)
        if(!this.hasOwnProperty(propName))
          continue;

        //Now the detail check and recursion

        //This returns the script back to the array comparing
        /**REQUIRES Array.equals**/
        if (this[propName] instanceof Array && object2[propName] instanceof Array) {
                   // recurse into the nested arrays
           if (!this[propName].equals(object2[propName]))
                        return false;
        }
        else if (this[propName] instanceof Object && object2[propName] instanceof Object) {
                   // recurse into another objects
                   //console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
           if (!this[propName].equals(object2[propName]))
                        return false;
        }
        //Normal value comparison for strings and numbers
        else if(this[propName] != object2[propName]) {
           return false;
        }
    }
    //If everything passed, let's say YES
    return true;
}  

그러나 이것은 클래스 인스턴스 및 기타 항목이 아닌 데이터와 같은 JSON을 비교하는 역할을한다는 것을 기억하십시오. mor 복잡한 객체를 비교하려면 이 답변과 superlong 기능을보십시오 .
이 작업을 수행하려면 Array.equals원래 기능을 약간 편집해야합니다.

...
    // Check if we have nested arrays
    if (this[i] instanceof Array && array[i] instanceof Array) {
        // recurse into the nested arrays
        if (!this[i].equals(array[i]))
            return false;
    }
    /**REQUIRES OBJECT COMPARE**/
    else if (this[i] instanceof Object && array[i] instanceof Object) {
        // recurse into another objects
        //console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
        if (!this[i].equals(array[i]))
            return false;
        }
    else if (this[i] != array[i]) {
...

나는 두 기능 모두에 대해 작은 테스트 도구를 .

보너스 : 중첩 배열 indexOfcontains

Samy Bencherif는 중첩 배열에서 특정 객체를 검색하는 경우 유용한 기능을 준비 했습니다. https://jsfiddle.net/SamyBencherif/8352y6yw/


27
엄격한 비교를하려면 this[i] !== array[i]대신을 사용하십시오 !=.
Tim S.

38
equals대신 메소드를 호출해야합니다 compare. 적어도 .NET에서 compare는 일반적으로 어느 객체가 다른 객체보다 큰지를 나타내는 부호있는 int를 반환합니다. Comparer.Compare 참조하십시오 .
Oliver

15
이것이 올바른 방법 일뿐 만 아니라 훨씬 더 효율적입니다. 이 질문에 제안 된 모든 방법을 위해 준비한 빠른 jsperf 스크립트가 있습니다. jsperf.com/comparing-arrays2
Tolga E

96
내장 타입의 프로토 타입을 변경하는 것은 올바른 방법이
Jasper

31
또한 다시 작성하기 쉬운 지 여부에 관한 것이 아니라 잘못된 연습으로 간주되는 것을 권장하지 않아야한다는 사실 ( developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/… )에 대한 답변입니다. 확실히 헤더 아래에 "올바른 방법"이 작업을 수행 할
재스퍼

386

이것은 스칼라 배열에서만 작동하지만 (아래 참고 참조) 짧습니다.

array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})

RMA, ECMAScript 6 / CoffeeScript / 화살표 기능이있는 TypeScript에서 :

array1.length === array2.length && array1.every((value, index) => value === array2[index])

(참고 : 여기서 'scalar'는 ===숫자, 문자열, 참조 객체, 참조 함수를 사용하여 직접 비교할 수있는 값을 의미합니다 . 비교 연산자에 대한 자세한 내용 은 MDN 참조참조 하십시오 ).

최신 정보

주석에서 읽은 내용에서 배열을 정렬하고 비교하면 정확한 결과를 얻을 수 있습니다.

array1.length === array2.length && array1.sort().every(function(value, index) { return value === array2.sort()[index]});

예 :

array1 = [2,3,1,4];
array2 = [1,2,3,4];

그런 다음 위의 코드는 true


19
독자는 이것이 정렬 된 배열에서만 작동한다는 것을 알고 있어야하지만 이것을 좋아합니다.
Ellen Spertus

13
@espertus로 정렬되거나 정렬되지 않은 모든 종류의 배열에서 작동합니다.
Michał Miszczyszyn

36
그렇습니다. 이 함수는 두 개의 배열을 비교하는 것으로 가정되며, 정렬 여부에 관계없이 연속 요소가 같아야합니다.
Michał Miszczyszyn

22
@espertus 요소가 두 배열에서 정확히 같은 순서를 갖지 않으면 true를 반환하지 않습니다. 그러나 평등 검사의 목표는 동일한 요소가 포함되어 있는지 확인하는 것이 아니라 동일한 순서로 동일한 요소가 있는지 확인하는 것입니다.
Quentin Roy

7
당신이 두 배열은 (여러 번 사용할 수 있지만) 같은 정렬되지 않은 항목을 포함 같음, 있는지 확인하려는 경우, 당신은 사용할 수 있습니다 a1.length==a2.length && a1.every((v,i)=>a2.includes(v)): var a1 =[1,2,3], a2 = [3,2,1];( var a1 =[1,3,3], a2 = [1,1,3];작업은 예상하지 않으므로)
MEMS

208

Underscore 및 Lodash에서 배열 / 객체 무거운 코딩 프로젝트에 Underscore 라이브러리를 사용하고 싶습니다. 배열 또는 객체를 비교할 때 다음과 같습니다.

_.isEqual(array1, array2)   // returns a boolean
_.isEqual(object1, object2) // returns a boolean

22
주문이 중요합니다 _.isEqual([1,2,3], [2,1,3]) => false
Vitaliy Alekask

3
isEqual기능 만 원한다면 lodash.isequal 모듈을 사용할 수 있습니다
hellatan

6
_.difference ();를 사용할 수 있습니다. 주문이 중요하지 않은 경우
Ronan Quillevere

5
순서가 중요하지 않은 경우이 검사 전에 배열을 정렬 할 수 있습니다._.isEqual([1,2,3].sort(), [2,1,3].sort()) => true
Filype

가장 간결하고 간단한 답변 IMHO :-)
Kieran Ryan

121

이것은 JSON stringify를 사용하여 수행하는 가장 간단한 방법이며 일부 상황에서 가장 좋은 솔루션 일 수 있습니다.

JSON.stringify(a1) === JSON.stringify(a2);

이렇게하면 객체 a1a2문자열 로 변환되어 비교할 수 있습니다. 위의 답변 중 하나에 표시된 정렬 알고리즘을 사용하여 객체를 정렬 할 수 있기 때문에 대부분의 경우 순서가 중요합니다.

더 이상 객체를 비교하지 않고 객체의 문자열 표현을 유의하십시오. 정확히 원하는 것이 아닐 수도 있습니다.


좋은 대답이지만 왜 [] == []이 false를 반환합니까? 둘 다 단순한 물체라면 왜일까요?
Pardeep Jain

4
@PardeepJain은 기본적으로 ECMAScript for Objects의 항등 연산자가 동일한 메모리 위치를 참조 할 때 true를 반환하기 때문입니다. var x = y = []; // 이제 평등은 true를 반환합니다.
radtek

7
JSON stringify 함수는 빠르지 않습니다. 더 큰 배열과 함께 사용하면 분명히 지연이 발생합니다.
루카스 리에 시스

6
이 질문은 특히 JSON.stringify를 사용하는 것보다 낫고 빠른 방법이 있는지 묻습니다 .
돈 해치

왜 이것이 어떤 상황에서 좋은 해결책이 될 수 있는지에 대해 자세히 설명합니다.
radtek

61

"동일한"이라는 말의 의미가 확실하지 않습니다. 예를 들어, 배열 ab아래가 동일합니까 (중첩 배열에 유의)?

var a = ["foo", ["bar"]], b = ["foo", ["bar"]];

다음은 엄격한 등식을 사용하여 각 배열의 해당 요소를 차례로 비교하고 자체 배열 인 배열 요소의 재귀 비교를 수행하지 않는 최적화 된 배열 비교 함수입니다. 위의 예에서는 arraysIdentical(a, b)을 반환 false합니다. 일반적인 경우에는 작동하며 JSON 및 join()기반 솔루션은 다음을 수행하지 않습니다.

function arraysIdentical(a, b) {
    var i = a.length;
    if (i != b.length) return false;
    while (i--) {
        if (a[i] !== b[i]) return false;
    }
    return true;
};

@ASDF : "동일한"의미가 무엇인지 확실하지 않습니다. 분명히이 대답은 얕은 점검을합니다. 메모를 추가하겠습니다.
Tim Down

이것은 배열에 대해 실패합니다.
Gopinath Shiva

4
@GopinathShiva : 글쎄, 당신이 그것을 기대할 때만 실패합니다 true. 대답은 그렇지 않다고 설명합니다. 중첩 배열을 비교해야하는 경우 재귀 검사를 쉽게 추가 할 수 있습니다.
Tim Down

59

실용적인 방법

"올바르지 않은"솔루션과 달리 "올바른"( "올바른") 경우 특정 구현이 "The Right Way ™"라고 말하는 것이 잘못이라고 생각합니다. Tomáš의 솔루션은 문자열 기반 배열 비교에 비해 명백히 개선 된 것이지만 이것이 객관적으로 "옳다"는 것을 의미하지는 않습니다. 무엇 권리 어쨌든은? 가장 빠릅니까? 가장 유연합니까? 이해하기가 가장 쉬운가요? 디버깅하는 것이 가장 빠릅니까? 가장 적은 작업을 사용합니까? 부작용이 있습니까? 어떤 솔루션도 모든 것을 최대한 활용할 수는 없습니다.

Tomáš는 그의 솔루션이 빠르다고 말할 수 있지만 필연적으로 복잡하다고 말합니다. 중첩 여부에 관계없이 모든 어레이에서 작동하는 올인원 솔루션이 되려고합니다. 실제로, 그것은 단지 배열 이상의 것을 입력으로 받아들이고 여전히 "유효한"대답을 시도합니다.


일반은 재사용 성을 제공합니다

내 대답은 문제에 다르게 접근합니다. arrayCompare배열을 통한 스테핑에만 관련된 일반적인 절차 부터 시작하겠습니다 . 여기에서 arrayEqualand arrayDeepEqual등 의 다른 기본 비교 함수를 작성합니다.

// arrayCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayCompare = f => ([x,...xs]) => ([y,...ys]) =>
  x === undefined && y === undefined
    ? true
    : Boolean (f (x) (y)) && arrayCompare (f) (xs) (ys)

내 의견으로는, 가장 좋은 종류의 코드는 주석이 필요하지 않으며 예외는 아닙니다. 거의 아무런 노력 없이이 절차의 동작을 이해할 수 있도록 여기에는 거의 일어나지 않습니다. 물론, ES6 구문 중 일부는 현재 여러분에게 이질적으로 보이지만 ES6이 비교적 새롭기 때문입니다.

형식에서 알 수 있듯이 arrayCompare비교 함수, f두 개의 입력 배열 xs및을 사용 ys합니다. 대부분의 f (x) (y)경우 입력 배열의 각 요소를 호출 하기 만하면됩니다. 단락 평가 덕분에 false사용자가 정의한 f반품 일 경우 조기에 반품합니다 . 따라서, 이것은 비교기가 반복을 조기에 중단하고 불필요 할 때 나머지 입력 배열을 통한 루핑을 방지 할 수 있음을 의미합니다.false&&


엄격한 비교

다음으로 arrayCompare함수를 사용하여 필요한 다른 함수를 쉽게 만들 수 있습니다. 우리는 초등학교에서 시작합니다 arrayEqual...

// equal :: a -> a -> Bool
const equal = x => y =>
  x === y // notice: triple equal

// arrayEqual :: [a] -> [a] -> Bool
const arrayEqual =
  arrayCompare (equal)

const xs = [1,2,3]
const ys = [1,2,3]
console.log (arrayEqual (xs) (ys))      //=> true
// (1 === 1) && (2 === 2) && (3 === 3)  //=> true

const zs = ['1','2','3']
console.log (arrayEqual (xs) (zs))      //=> false
// (1 === '1')                          //=> false

그렇게 간단합니다. (엄격한 평등을 위해) 를 사용 하는 것과 비교하는 비교기 함수 arrayEqual로 정의 할 수 있습니다 .arrayCompareab===

우리는 또한 equal자신의 기능으로 정의 합니다. 이것은 arrayCompare다른 데이터 유형 (배열)의 맥락에서 첫 번째 비교기를 활용하는 고차 함수 의 역할을 강조합니다 .


느슨한 비교

우리는 그냥 간단하게 정의 할 수 arrayLooseEqual사용하는 ==대신합니다. 이제 1(Number)를'1' (String) 하면 결과는 다음과 같습니다 true.

// looseEqual :: a -> a -> Bool
const looseEqual = x => y =>
  x == y // notice: double equal

// arrayLooseEqual :: [a] -> [a] -> Bool
const arrayLooseEqual =
  arrayCompare (looseEqual)

const xs = [1,2,3]
const ys = ['1','2','3']
console.log (arrayLooseEqual (xs) (ys))    //=> true
// (1 == '1') && (2 == '2') && (3 == '3')  //=> true

깊은 비교 (재귀)

아마도 이것은 단지 얕은 비교 방법이라는 것을 알았을 것입니다. Tomáš의 솔루션은 "The Right Way ™"입니다. 암묵적인 심층 비교를하기 때문입니다.

글쎄, 우리의 arrayCompare절차는 깊은 평등 테스트를 산들 바람으로 만드는 방법으로 사용할 수있을 정도로 다재다능합니다…

// isArray :: a -> Bool
const isArray =
  Array.isArray

// arrayDeepCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayDeepCompare = f =>
  arrayCompare (a => b =>
    isArray (a) && isArray (b)
      ? arrayDeepCompare (f) (a) (b)
      : f (a) (b))

const xs = [1,[2,[3]]]
const ys = [1,[2,['3']]]
console.log (arrayDeepCompare (equal) (xs) (ys)) //=> false
// (1 === 1) && (2 === 2) && (3 === '3')         //=> false

console.log (arrayDeepCompare (looseEqual) (xs) (ys)) //=> true
// (1 == 1) && (2 == 2) && (3 == '3')                 //=> true

그렇게 간단합니다. 우리는 또 다른 고차 함수를 사용하여 깊은 비교기를 만듭니다. 이번에 는 배열 과 배열 arrayCompare인지 확인하는 사용자 지정 비교기를 사용하여 줄 바꿈 합니다. 그렇다면 다른 방법으로 다시 비교 하고 사용자 지정 비교기 ( )와 비교 하십시오. 이를 통해 우리는 개별 요소를 실제로 비교하는 방법과 깊은 비교 동작을 유지할 수 있습니다. 즉, 위의 예에서 볼 수 있듯이abarrayDeepCompareabfequal , looseEqual또는 기타 비교기는 우리가합니다.

arrayDeepCompare카레 이기 때문에 이전 예제에서와 마찬가지로 부분적으로 적용 할 수 있습니다.

// arrayDeepEqual :: [a] -> [a] -> Bool
const arrayDeepEqual =
  arrayDeepCompare (equal)

// arrayDeepLooseEqual :: [a] -> [a] -> Bool
const arrayDeepLooseEqual =
  arrayDeepCompare (looseEqual)

필자는 필요에 따라 어레이에 대해 얕거나 깊은 비교를 명시 적으로 선택할 수 있기 때문에 Tomáš 솔루션보다 이미 분명히 개선되었습니다 .


객체 비교 (예)

이제 객체 배열이나 무언가가 있다면 어떨까요? 각 객체의 id값 이 동일한 경우 해당 배열을 "동일"한 것으로 간주하고 싶을 수도 있습니다 .

// idEqual :: {id: Number} -> {id: Number} -> Bool
const idEqual = x => y =>
  x.id !== undefined && x.id === y.id

// arrayIdEqual :: [a] -> [a] -> Bool
const arrayIdEqual =
  arrayCompare (idEqual)

const xs = [{id:1}, {id:2}]
const ys = [{id:1}, {id:2}]
console.log (arrayIdEqual (xs) (ys)) //=> true
// (1 === 1) && (2 === 2)            //=> true

const zs = [{id:1}, {id:6}]
console.log (arrayIdEqual (xs) (zs)) //=> false
// (1 === 1) && (2 === 6)            //=> false

그렇게 간단합니다. 여기서는 바닐라 JS 객체를 사용했지만이 유형의 비교기는 모든 객체 유형에서 작동 할 수 있습니다 . 심지어 커스텀 객체까지. 이러한 종류의 동등성 테스트를 지원하기 위해 Tomáš의 솔루션을 완전히 재 작업해야합니다.

객체가있는 깊은 배열? 문제가 아니다. 우리는 매우 다양한 범용 기능을 구축하여 다양한 사용 사례에서 작동합니다.

const xs = [{id:1}, [{id:2}]]
const ys = [{id:1}, [{id:2}]]
console.log (arrayCompare (idEqual) (xs) (ys))     //=> false
console.log (arrayDeepCompare (idEqual) (xs) (ys)) //=> true

임의 비교 (예)

아니면 다른 종류의 완전히 임의적 인 비교를 원한다면 어떨까요? 어쩌면 나는 각각 x이 각각 보다 큰지 알고 싶습니다 y...

// gt :: Number -> Number -> Bool
const gt = x => y =>
  x > y

// arrayGt :: [a] -> [a] -> Bool
const arrayGt = arrayCompare (gt)

const xs = [5,10,20]
const ys = [2,4,8]
console.log (arrayGt (xs) (ys))     //=> true
// (5 > 2) && (10 > 4) && (20 > 8)  //=> true

const zs = [6,12,24]
console.log (arrayGt (xs) (zs))     //=> false
// (5 > 6)                          //=> false

더 적은

더 적은 코드로 더 많은 일을하고 있음을 알 수 있습니다. arrayCompare자체적으로 복잡한 것은 없으며 우리가 만든 각 커스텀 비교기는 매우 간단한 구현을 가지고 있습니다.

쉽게, 우리는 두 배열을 비교하는 우리가 원하는 방법을 정확하게 정의 할 수 있습니다 - 얕은 깊이, 엄격한, 느슨한, 일부 객체 속성, 또는 임의의 계산, 또는 이들의 조합 - 모두가 하나 개의 절차를 사용하여 , arrayCompare. 어쩌면 RegExp비교기를 꿈꾸기도합니다 ! 아이들이 어떻게 정규 표현식을 좋아하는지 알고 있습니다.…

가장 빠릅니까? 아니. 그러나 아마도 둘 중 하나 일 필요는 없습니다. 속도가 코드의 품질을 측정하는 데 사용되는 유일한 지표 인 경우, 정말 많은 훌륭한 코드가 버려 질 것입니다. 이것이 바로이 방법을 Practical Way 라고 부르는 이유 입니다. 아니면 더 공정, 할 수 실용적인 방법. 이 답변은 다른 답변과 비교하여 실용적이라고 말하지 않기 때문에이 답변에 적합합니다. 객관적으로 사실입니다. 우리는 추론하기 쉬운 코드가 거의 없어 높은 수준의 실용성을 달성했습니다. 다른 코드에서는이 설명을 얻지 못했다고 말할 수 없습니다.

그것이 당신에게 "올바른"솔루션이됩니까? 그것은 당신 이 결정할 일입니다. 그리고 아무도 당신을 위해 그렇게 할 수 없습니다. 오직 당신 만이 당신의 요구를 알고 있습니다. 거의 모든 경우에, 나는 영리하고 빠른 종류보다 간단하고 실용적이며 다양한 코드를 소중하게 생각합니다. 당신이 중요하게 생각하는 것은 다를 수 있으므로 자신에게 맞는 것을 선택하십시오.


편집하다

나의 오래된 대답은 arrayEqual작은 절차로 분해하는 데 더 집중되었습니다 . 그것은 흥미로운 운동이지만 실제로이 문제에 접근하는 가장 (가장 실용적인) 방법은 아닙니다. 관심이 있으시면이 개정 내역을 볼 수 있습니다.


8
"가장 좋은 종류의 코드는 주석이 필요하지 않습니다"... 말하기는 싫지만이 코드는 주석을 더 많이 사용하거나 다른 이름을 사용할 수 있습니다. "비교"는 매우 모호합니다. 내가 정확하게 읽고 있다면, "비교"는 본질적으로 카레 재귀 "모든"입니다. 내 생각에 아니면 카레 재귀 "일부"입니까? 흠. 이것은 필요 이상으로 많은 생각을 요구하고 있습니다. 아마도 "등가 관계"라는 표준 용어를 활용하여 "arraysEquivalent"이 더 나은 이름 일 것입니다. 또는 "재귀 적으로 동등한"더 명확합니다.
Don Hatch

1
답장을 보내 주셔서 감사합니다. "비교하다"는 뜻 arrayCompare입니까? 예 함수는 카레이지만, 다르다 someevery. arrayCompare비교하는 데 비교기와 배열이 필요합니다. 임의의 함수를 사용하여 배열을 비교할 수 있기 때문에 특히 일반적인 이름을 선택했습니다. 이 함수는 새로운 배열 비교 함수 (예 :)를 생성하도록 전문화 될 수 있도록 커리 arrayEqual됩니다. 더 나은 이름을 제안 할 수 있습니까? 추가 의견이나 설명이 필요한 영역은 무엇입니까? ^ _ ^에 대해 기쁘게 생각합니다.
감사합니다

1
내 요점이 아직 확실하지 않은지 확실하지는 않지만 내 요지는 귀하의 함수가 실제로 임의의 함수 를 취하기위한 것이 아니며 , 생각하지 않습니다. 동일 관계 를 취하기위한 것이며 동등 관계 를 반환합니다. 그것은 중요하다. 내가 언급 한 것과 같은 다른 종류의 임의의 이진 함수, 심지어 사람들이 종종 "비교"라고 부르는 임의의 이진 함수를 제공한다면 현명한 일을하지 않을 것이다. 따라서 "비교"대신 "동등한"이름을 사용하는 것이 도움이 될 것입니다.
Don Hatch

1
@ftor, author : 매우 유용한 답변, 훌륭한 작업, +1. 피드백 : 단순성을 옹호하지만 한 줄에 세 개의 화살표가있는 표현은 많은 개발자에게 간단하거나 이해하기 쉬운 방법이 아닙니다. 예 : f => ([x, ... xs]) => ([y, ... ys]) =>. 나는 이것을 지속적으로 사용하고 있으며 "그냥 바라보기"보다는 정신적으로 분해해야했다. 두 번째 포인트 ftor가 맞습니다. 매번 사용하십시오. 당신의 이유를 칭찬해도 균형을 잡는 것이 나에게뿐만 아니라 디자인 철학을 추론하려고 할 때의 관점에서도 더 나아 보입니다.
whitneyland

1
나는 이것이 학습의 장소라는 것을 이해하지만, 여기서는 기능적 스타일을 연구하는 일반 프로그래머는 모든 커리 기능을 커리되지 않은 기능으로 변환 할 수 있다고 가정합니다. 내 대답은이 스타일 이 자신의 프로그램에서 사용되어야한다는 제안을하지 않습니다. 커리되지 않은 스타일 로 작성하고, 들여 쓰기 규칙을 사용하여 작성하고 원하는대로 작성하십시오. 프로그램 최고. 또한 우리가 프로그램을 구문 적으로 표현하는 방식에 도전하도록 다른 사람들을 초대하고 싶습니다.
감사합니다.

54

원래 질문의 정신에서 :

두 배열을 이상적으로 효율적 으로 비교하고 싶습니다 . 공상 은 없으며, 동일하면 사실이고 그렇지 않으면 거짓입니다.

여기에 제안 된 더 간단한 제안 중 일부에 대해 성능 테스트를 실행하여 다음과 같은 결과를 얻었습니다 (빠르거나 느림).

반면 (67 %) 팀 아래로

var i = a1.length;
while (i--) {
    if (a1[i] !== a2[i]) return false;
}
return true

모든 (69 %) user2782196하여

a1.every((v,i)=> v === a2[i]);

감소 (74 %) DEIs하여

a1.reduce((a, b) => a && a2.includes(b), true);

Gaizka Allende & vivek의 join & toString (78 %)

a1.join('') === a2.join('');

a1.toString() === a2.toString();

Victor Palomo의 반 문자열 (90 %)

a1 == a2.toString();

radtek으로 stringify (100 %)

JSON.stringify(a1) === JSON.stringify(a2);

참고 배열은 단일 차원 배열을 분류하는 것으로 가정 아래의 예. .length공통 벤치 마크에 대한 비교가 제거되었습니다 ( a1.length === a2.length제안에 추가 하면 성능이 ~ 10 % 향상됩니다). 각각의 속도와 한계를 아는 데 가장 적합한 솔루션을 선택하십시오.

관련이없는 메모 : 사람들이이 질문에 완벽하게 합법적 인 답변을 내리기 위해 투표 버튼에서 모든 트리거 행복 John Waynes를 얻는 것이 흥미 롭습니다.


링크는 빈 테스트를 엽니 다.
Alexander Abakumov 2016 년

배열 크기가 부딪 치면이 숫자는 적용되지 않습니다 (특히 축소 방식). Array.from({length: 1000}).map((a,v)=> $ {v}로 시도.padStart(10,2));
Narayon

얕은 배열에서만 작동
Ramesh Rajendran

28

Tomáš Zato의 답변을 바탕으로 배열을 반복하는 것이 가장 빠릅니다. 또한 (다른 사람들이 이미 언급했듯이) 함수는 비교하지 않고 같음 / 같음이라고해야합니다. 이것에 비추어, 나는 비슷한 점에 대한 배열 비교를 처리하기 위해 함수를 수정했다.

Array.prototype.equals = function (array, strict) {
    if (!array)
        return false;

    if (arguments.length == 1)
        strict = true;

    if (this.length != array.length)
        return false;

    for (var i = 0; i < this.length; i++) {
        if (this[i] instanceof Array && array[i] instanceof Array) {
            if (!this[i].equals(array[i], strict))
                return false;
        }
        else if (strict && this[i] != array[i]) {
            return false;
        }
        else if (!strict) {
            return this.sort().equals(array.sort(), true);
        }
    }
    return true;
}

이 함수는 기본값 인 true로 추가 매개 변수를 사용합니다. 이 엄격한 매개 변수는 배열이 내용과 내용의 순서에서 모두 동일해야하는지 또는 단순히 동일한 내용을 포함해야하는지 여부를 정의합니다.

예:

var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 4, 3];  // Loosely equal to 1
var arr3 = [2, 2, 3, 4];  // Not equal to 1
var arr4 = [1, 2, 3, 4];  // Strictly equal to 1

arr1.equals(arr2);         // false
arr1.equals(arr2, false);  // true
arr1.equals(arr3);         // false
arr1.equals(arr3, false);  // false
arr1.equals(arr4);         // true
arr1.equals(arr4, false);  // true

나는 또한 기능을 가진 빠른 jsfiddle이 예까지 작성했습니다 :
http://jsfiddle.net/Roundaround/DLkxX/


12

여기에는 많은 답변이 있지만 도움이되는 것으로 생각됩니다.

const newArray = [ ...new Set( [...arr1, ...arr2] ) ]

배열의 구조가 어떻게 보일지에 대해서는 질문에 언급되어 있지 않으므로 배열에 배열이나 객체가 중첩되어 있지 않다는 것을 알고 있다면 (나에게 일어난 이유입니다. 답변) 위의 코드가 작동합니다.

우리는 확산 연산자 (...)를 사용하여 두 배열을 연결 한 다음 Set을 사용하여 중복을 제거합니다. 일단 당신이 그들의 크기를 비교할 수 있다면, 세 개의 배열이 모두 같은 크기를 가지면 당신은 갈 수 있습니다.

이 대답은 또한 요소의 순서를 무시합니다. 내가 말했듯이 정확한 상황은 나에게 일어 났으므로 같은 상황에있는 누군가가 여기에서 끝날 수 있습니다.


편집 1.

Dmitry Grinko의 질문에 대한 답변 : "왜 스프레드 연산자 (...)를 사용하셨습니까?-... 새 세트? 작동하지 않습니다."

이 코드를 고려하십시오.

const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ new Set( [...arr1, ...arr2] ) ]
console.log(newArray)

당신은 얻을 것이다

[ Set { 'a', 'b', 'c' } ]

이 값으로 작업하려면 일부 Set 속성을 사용해야합니다 ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set 참조 ). 반면에이 코드를 사용하면 :

const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
console.log(newArray)

당신은 얻을 것이다

[ 'a', 'b', 'c' ]

차이점은 전자가 나에게 세트를 제공한다는 것입니다. 세트의 크기를 얻을 수있을 때도 작동하지만 후자는 나에게 필요한 배열을 제공합니다. 해상도에 더 직접적인 것입니다.


왜 스프레드 연산자 (...)를 사용 했습니까? 작동하지 않습니다.
Dmitry Grinko

Dmitry Grinko 나는 Edit1에 대한 귀하의 질문에 대답했다고 생각합니다. 그러나 두 가지 답변 모두 방해가 될 수 있으므로 '작동하지 않습니다'라고 말하는 것이 무슨 의미인지 잘 모르겠습니다.
Jeferson Euclides

10

JSON.encode와 같은 줄에 join ()을 사용하는 것입니다.

function checkArrays( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;


    //slice so we do not effect the original
    //sort makes sure they are in order
    //join makes it a string so we can do a string compare
    var cA = arrA.slice().sort().join(","); 
    var cB = arrB.slice().sort().join(",");

    return cA===cB;

}

var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];  //will return true

console.log( checkArrays(a,b) );  //true
console.log( checkArrays(a,c) );  //false
console.log( checkArrays(a,d) );  //false
console.log( checkArrays(a,e) );  //true

마지막 비교 테스트 유형에 관심이있는 경우에만 문제가됩니다. 유형에 관심이 있다면 반복해야합니다.

function checkArrays( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;

    //slice so we do not effect the orginal
    //sort makes sure they are in order
    var cA = arrA.slice().sort(); 
    var cB = arrB.slice().sort();

    for(var i=0;i<cA.length;i++){
         if(cA[i]!==cB[i]) return false;
    }

    return true;

}

var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];

console.log( checkArrays(a,b) );  //true
console.log( checkArrays(a,c) );  //false
console.log( checkArrays(a,d) );  //false
console.log( checkArrays(a,e) );  //false

순서가 루프 인 것보다 동일하게 유지되어야하는 경우 정렬이 필요하지 않습니다.

function checkArrays( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;


    for(var i=0;i<arrA.length;i++){
         if(arrA[i]!==arrB[i]) return false;
    }

    return true;

}

var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];

console.log( checkArrays(a,a) );  //true
console.log( checkArrays(a,b) );  //false
console.log( checkArrays(a,c) );  //false
console.log( checkArrays(a,d) );  //false
console.log( checkArrays(a,e) );  //false

3
이것은 특정 배열에서만 작동하며 큰 배열에서는 매우 느립니다.
Tomáš

2
JSON 생성도 반복됩니다. 아직 알지 못합니다. 루핑 외에도 JSON 생성에는 더 많은 메모리가 필요합니다. 비교하기 전에 해당 배열의 문자열 표현을 2 개 만듭니다. downwote 기능은 최고에서 최고로 답변을 주문하기 위해 구현됩니다. 귀하의 답변이 좋은 답변이 아니라고 생각합니다.
Tomáš

2
죄송합니다. 방금 JSON 대신에 말했습니다 .join(). 어쩌면 두 번째 솔루션을 1 차 솔루션으로 언급 한 경우 (다차원 배열에 대해서는 아무런 문제가 없지만 더 나은 솔루션이므로) 그렇게 판단하지는 않을 것입니다. 지금까지 배열을 문자열로 변환하는 모든 답변을 정리했습니다. 또한, 당신이 알아야 할 경우를 대비하여 올바른 방법을 사용하는 모든 것을 찬성했습니다. 이것은 @Tim Down의 대답과 Bireys의 것을 의미합니다.
Tomáš Zato-복원 모니카

6
첫 번째 버전 FAILS : checkArrays([1,2,3] , ["1,2",3]) == true, 그리고 이것이 당신이 원하는 것 같지 않을 것입니다!
Doin

2
@epascarello : 예, 할 수는 있지만 (매우 긴 구분 기호의 비 효율성을 제외하면) checkArrays () 함수가 잘못 작동하는 경우 (배열에 구분 기호가있는 문자열이 포함되는 경우)가 있음을 의미합니다 . 배열의 내용에 대해 알고 있으면 배열 항목에 포함되지 않을 구분 기호를 선택할 수 있지만 일반적인 배열 비교 를 작성하려는 경우에는 문제가되지 않습니다. 이 기능을 사용 join()하면 미묘하게 버그가 있습니다!
Doin

7

다음은 Typescript 버전입니다.

//https://stackoverflow.com/a/16436975/2589276
export function arraysEqual<T>(a: Array<T>, b: Array<T>): boolean {
    if (a === b) return true
    if (a == null || b == null) return false
    if (a.length != b.length) return false

    for (var i = 0; i < a.length; ++i) {
        if (a[i] !== b[i]) return false
    }
    return true
}

//https://stackoverflow.com/a/16436975/2589276
export function arraysDeepEqual<T>(a: Array<T>, b: Array<T>): boolean {
    return JSON.stringify(a) === JSON.stringify(b)
}

모카에 대한 몇 가지 테스트 사례 :

it('arraysEqual', function () {
    let a = [1,2]
    let b = [1,2]
    let c = [2,3]
    let d = [2, 3]
    let e = ['car','apple','banana']
    let f = ['car','apple','banana']
    let g = ['car','apple','banan8']

    expect(arraysEqual(a, b)).to.equal(true)
    expect(arraysEqual(c, d)).to.equal(true)
    expect(arraysEqual(a, d)).to.equal(false)
    expect(arraysEqual(e, f)).to.equal(true)
    expect(arraysEqual(f, g)).to.equal(false)
})

it('arraysDeepEqual', function () {
    let a = [1,2]
    let b = [1,2]
    let c = [2,3]
    let d = [2, 3]
    let e = ['car','apple','banana']
    let f = ['car','apple','banana']
    let g = ['car','apple','banan8']
    let h = [[1,2],'apple','banan8']
    let i = [[1,2],'apple','banan8']
    let j = [[1,3],'apple','banan8']

    expect(arraysDeepEqual(a, b)).to.equal(true)
    expect(arraysDeepEqual(c, d)).to.equal(true)
    expect(arraysDeepEqual(a, d)).to.equal(false)
    expect(arraysDeepEqual(e, f)).to.equal(true)
    expect(arraysDeepEqual(f, g)).to.equal(false)
    expect(arraysDeepEqual(h, i)).to.equal(true)
    expect(arraysDeepEqual(h, j)).to.equal(false)
})

6

Chai 어설 션 라이브러리 와 함께 Mocha 와 같은 테스트 프레임 워크를 사용하는 경우 배열을 비교하기 위해 깊은 평등을 사용할 수 있습니다 .

expect(a1).to.deep.equal(a2)

배열이 해당 인덱스에서 동일한 요소를 갖는 경우에만 true를 리턴해야합니다.


6

그것들이 숫자 또는 문자열의 두 배열 만 있다면, 이것은 빠른 한 줄입니다

const array1 = [1, 2, 3];
const array2 = [1, 3, 4];
console.log(array1.join(',') === array2.join(',')) //false

const array3 = [1, 2, 3];
const array4 = [1, 2, 3];
console.log(array3.join(',') === array4.join(',')) //true

const 배열 1 = [1]; const 배열 2 = [1, 1]; CONSOLE.LOG (array1.join ( '') === array2.join ( '')) // true를 반환
댄 M.

그것이 안 : array1.join ( '')는 '1'과 array2.join ( '')는 '11'
Gaizka 아옌데

미안, 오타 첫 번째 배열은입니다 [11]. 왜 이런 일이 발생하고 어떻게 해결해야하는지 분명합니다.
Dan M.

당신이 무슨 일인지 잘 모르겠습니다. 아주 간단합니다. [1] .join ()은 "1"이고 [1,1] .join ()은 "1,1"이므로 결코 같지 않습니다.
Gaizka Allende

제 의견을 더 자세히 읽으십시오. 그래도 보이지 않으면 ideone.com/KFu427
Dan M.

5

필자의 경우 비교 배열에는 숫자와 문자열 만 포함됩니다. 이 함수는 배열에 동일한 요소가 포함되어 있는지 보여줍니다.

function are_arrs_match(arr1, arr2){
    return arr1.sort().toString() === arr2.sort().toString()
}

테스트 해보자!

arr1 = [1, 2, 3, 'nik']
arr2 = ['nik', 3, 1, 2]
arr3 = [1, 2, 5]

console.log (are_arrs_match(arr1, arr2)) //true
console.log (are_arrs_match(arr1, arr3)) //false

이 질문은 정렬을 요구하지 않으므로와 같은 예에서는 해결책이 잘못되었습니다 are_arrs_equal([1,2], [2,1]). 또한 왜 스트링 화가 불필요하고 깨지기 쉬운 지에 대해서는이 페이지의 다른 토론을 참조하십시오.
모드를 잘 치료하십시오

are_arrs_equal([1,2], [2,1])true예상대로 반환합니다 . 아마도이 솔루션은 이상적이지 않지만 나를 위해 일했습니다.
yesnik

그것은 정확히 문제입니다. 그 두 가지는 순서지정된 데이터 구조에 대해 "같음"이라는 단어의 의미가 동일하지 않습니다 . 그것들은 집합이 아니라 배열이며, 평등을 원한다면 그것을 그것을 부르고 다른 질문에 대답해야합니다. :-)
당신의 개조를 치료

1
위의 의견에 동의하지만이 솔루션은 순서가 중요하지 않은 간단한 정수 배열에서도 작동하므로 사용합니다.
tomazahlin

1
실패 are_arrs_match([1,2], ["1,2"])( true). 그리고 the sort()호출은 입력 배열수정합니다 -이것은 바람직하지 않을 수 있습니다.
try-catch-finally

5

정렬되지 않은 2 개의 배열을 비교합니다.

function areEqual(a, b) {
  if ( a.length != b.length) {
    return false;
  }
  return a.filter(function(i) {
    return !b.includes(i);
  }).length === 0;  
}

비싸지 만 (컴퓨팅 리소스 측면에서) 이것은 다양한 유형에 적합하고 정렬에 의존하지 않는 강력한 솔루션입니다!
user3.1415927


4

우리는 이것을 사용하여 기능적인 방법으로 할 수 있습니다. every ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/every )

function compareArrays(array1, array2) {
    if (array1.length === array2.length)
        return array1.every((a, index) => a === array2[index])
    else
        return false
}

// test
var a1 = [1,2,3];
var a2 = [1,2,3];

var a3 = ['a', 'r', 'r', 'a', 'y', '1']
var a4 = ['a', 'r', 'r', 'a', 'y', '2']

console.log(compareArrays(a1,a2)) // true
console.log(compareArrays(a1,a3)) // false
console.log(compareArrays(a3,a4)) // false

4

두 배열의 요소가 같지만 순서가 같지 않으면 코드가 대소 문자를 적절하게 처리하지 않습니다.

요소가 숫자 인 두 배열을 비교하는 예제를 사용하여 내 코드를 살펴보면 다른 요소 유형 (.toString () 대신 .join ()을 사용하여)을 수정하거나 확장 할 수 있습니다.

var a1 = [1,2,3];
var a2 = [1,2,3];
const arraysAreEqual = a1.sort().toString()==a2.sort().toString();
// true if both arrays have same elements else false
console.log(arraysAreEqual);


3

그녀의 해결책은 다음과 같습니다.

/**
 * Tests two data structures for equality
 * @param {object} x
 * @param {object} y
 * @returns {boolean}
 */
var equal = function(x, y) {
    if (typeof x !== typeof y) return false;
    if (x instanceof Array && y instanceof Array && x.length !== y.length) return false;
    if (typeof x === 'object') {
        for (var p in x) if (x.hasOwnProperty(p)) {
            if (typeof x[p] === 'function' && typeof y[p] === 'function') continue;
            if (x[p] instanceof Array && y[p] instanceof Array && x[p].length !== y[p].length) return false;
            if (typeof x[p] !== typeof y[p]) return false;
            if (typeof x[p] === 'object' && typeof y[p] === 'object') { if (!equal(x[p], y[p])) return false; } else
            if (x[p] !== y[p]) return false;
        }
    } else return x === y;
    return true;
};

중첩 된 데이터 구조와 함께 작동하며 객체의 메서드를 무시합니다. 이 방법으로 Object.prototype을 확장한다고 생각조차하지 않습니다.이 작업을 한 번 시도하면 jQuery가 중단되었습니다.)

대부분의 어레이는 여전히 대부분의 직렬화 솔루션보다 빠릅니다. 아마도 객체 레코드 배열에 대한 가장 빠른 비교 방법 일 것입니다.


좋지 않다! 이러한 사실 포기 equal({}, {a:1})하고 equal({}, null)이 오류 아웃을하고equal({a:2}, null)
kristianlm

3
JSON.stringify(collectionNames).includes(JSON.stringify(sourceNames)) ?  array.push(collection[i]) : null

이것이 내가 한 방법입니다.


좋은 해결책-그러나 특정 프리미티브 또는 깊게 중첩 된 배열과 같이 의도 한대로 작동하지 않는 경우가 있습니다. 그래도 모든 상황에서 작동하기를 바랍니다
Ben Rondeau

3

2 개의 배열 비교 :

var arr1 = [1,2,3];
var arr2 = [1,2,3];

function compare(arr1,arr2)
{
  if((arr1 == arr2) && (arr1.length == arr2.length))
    return true;
  else
    return false;
}

호출 기능

var isBool = compare(arr1.sort().join(),arr2.sort().join());

=== 배열에 대해 예상대로 작동하지 않기 때문에이 답변은 작동하지 않습니다.
마이클 양

=== 여기에 아무런 의미가 없지만 대답은 작동합니다 (sort ()는 배열에서만 작동하기 때문에). ==조차도 작동합니다.
Amay Kulkarni

직접 해보십시오. 이 코드를 실행하면 false가 인쇄됩니다. 이는 실제 값 대신 배열의 참조 값을 == 및 ===로 비교하기 때문입니다. == 및 ===는 기본 유형 비교에만 사용됩니다.
Michael Yang

그것은 사실을 반환하지만, 우리는 그것을 사용했지만, '==='가 필요하지 않기 때문에 제거했습니다.
Amay Kulkarni

아, 정렬 및 결합 후 문자열로 변환하고 함수를 호출하는 것을 보지 못했습니다. 사과합니다.
Michael Yang

3

나는 일반 믿는 JS와 함께 ECMAScript 2015달콤한 이해하기 간단하다.

var is_arrays_compare_similar = function (array1, array2) {

    let flag = true;

    if (array1.length == array2.length) {

        // check first array1 object is available in array2 index
        array1.every( array_obj => {
            if (flag) {
                if (!array2.includes(array_obj)) {
                    flag = false;
                }
            }
        });

        // then vice versa check array2 object is available in array1 index
        array2.every( array_obj => {
            if (flag) {
                if (!array1.includes(array_obj)) {
                    flag = false;
                }
            }
        });

        return flag;
    } else {
        return false;
    }

}

누군가에게 도움이되기를 바랍니다.


1
왜 그 반대의 검사가 필요한가요? 우리는 배열의 크기가 같다는 것을 알고 있습니다. 따라서 array1의 모든 항목이 array2에도 있습니다. 그렇다면 왜 array2의 모든 항목이 array1에 있는지 확인해야합니까?
JeffryHouser 19

2

Tomáš Zato 아이디어 확장. Tomas의 Array.prototype.compare는 사실상 Array.prototype.compareIdentical이라고합니다.

다음을 통과합니다.

[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 2]]) === false;
[1, "2,3"].compareIdentical ([1, 2, 3]) === false;
[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].compareIdentical ([1, 2, 1, 2]) === true;

그러나 실패합니다 :

[[1, 2, [3, 2]],1, 2, [3, 2]].compareIdentical([1, 2, [3, 2],[1, 2, [3, 2]]])

여기 내 의견으로는 더 나은 버전이 있습니다.

Array.prototype.compare = function (array) {
    // if the other array is a falsy value, return
    if (!array)
        return false;

    // compare lengths - can save a lot of time
    if (this.length != array.length)
        return false;

    this.sort();
    array.sort();
    for (var i = 0; i < this.length; i++) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].compare(array[i]))
                return false;
        }
        else if (this[i] != array[i]) {
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;
        }
    }
    return true;
}

http://jsfiddle.net/igos/bcfCY/


2
-1. 주어진 예제에서 '실패'하면 '실패'의 다소 임의적 인 정의의 경우에만 해당됩니다. 왜 두 개의 다른 배열이 동일하다고 생각합니까? 여기에서 구현하려는 '평등'의 개념이나 그것이 합리적이거나 유용한 이유를 설명하지는 않았지만, 다차원 배열을 마치 단일 차원으로 축소 된 것처럼 비교하려는 것처럼 보입니다. 그들. 그렇다면, 당신은 그것을 달성하지 못했습니다.
Mark Amery

내가 유추 할 수있는 것에 기초하여, 그는 [1, 2, 3, 4]와 [1, 3, 2, 4]가 같은 것으로 비교되어야한다고 말합니다 (주문은 중요하지 않습니다).
Gautham Badhrinathan

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

function check(a, b) {
  return (a.length != b.length) ? false : 
  a.every(function(row, index) {
    return a[index] == b[index];
  });
}  

check(a1, a2);

////// 또는 ///////

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

function check(a, b) {
  return (a.length != b.length) ? false : 
  !(a.some(function(row, index) {
    return a[index] != b[index];
  }));
}  

check(a1, a2)

위와 같이 필요한 조건을 만족하면 완전히 반복되지 않는 기능도 있습니다.
Vasanth

2

코드가 거의없는 또 다른 접근법 ( Array reduceArray contains 사용 ) :

arr1.length == arr2.length && arr1.reduce((a, b) => a && arr2.includes(b), true)

순서의 평등도 비교하려면 다음을 수행하십시오.

arr1.length == arr2.length && arr1.reduce((a, b, i) => a && arr2[i], true)
  • length한 배열의 요소의 세트는 다른 하나의 서브 세트 만이 아니라고 확인 보장한다.

  • 감속기는 하나의 배열을 탐색하고 다른 배열의 각 항목을 검색하는 데 사용됩니다. 하나의 항목을 찾지 못하면 reduce 함수는를 반환합니다 false.

    1. 첫 번째 예에서는 요소가 포함되어 있는지 테스트되고 있습니다.
    2. 두 번째 예도 주문 확인

1
이 답변을 명확하게하기 위해 코드를 조금 설명해 주시겠습니까?
ted

1. 배열 길이를 비교하여 한 배열이 다른 배열의 부분 집합이 아닌지 확인합니다.
DEls

2. 감속기를 사용하여 하나의 배열을 살펴보고 다른 배열의 각 항목을 검색하십시오. 하나의 항목을 찾지 못하면 reduce 함수는 'false'를 반환합니다
DEls

@ DEls : 설명을 답변으로 수정했습니다 (약간 reworded 및 확장). 이제 댓글을 삭제하고 첫 번째 댓글과이 댓글을 쓸모없는 것으로 표시 할 수 있습니다.
try-catch-finally

2

간단한 접근법 :

function equals(a, b) {
    if ((a && !b) || (!a && b) || (!a && !b) || (a.length !== b.length)) {
        return false;
    }

    var isDifferent = a.some(function (element, index) { 
        return element !== b[index];
    });

    return !isDifferent;
}

2

이미 몇 가지 훌륭한 답변이 있지만 배열을 비교할 때 신뢰할 수있는 다른 아이디어를 공유하고 싶습니다. JSON.stringify ()를 사용하여 두 배열을 비교할 수 있습니다 . 배열에서 문자열을 만들고 두 배열에서 얻은 두 문자열을 동일한 지 비교합니다.

JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:1},2]) //true

JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},2]) //false

JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},[3,4],2]) //false

JSON.stringify([1,{a:1},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //false

JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //true

JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false

JSON.stringify([1,{a:2},[3,4,[4]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false

JSON.stringify([1,{a:2},[3,4,[5]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //true

2

재귀NESTED 배열에서 작동 합니다.

function ArrEQ(a1,a2){
   return( 
        //:Are both elements arrays?
        Array.isArray(a1)&&Array.isArray(a2) 
        ?
        //:Yes: Test each entry for equality:
        a1.every((v,i)=>(ArrEQ(v,a2[i])))
        :
        //:No: Simple Comparison:
        (a1===a2)
   );;
};;

console.log( "Works With Nested Arrays:" );
console.log( ArrEQ( 
    [1,2,3,[4,5,[6,"SAME/IDENTICAL"]]],
    [1,2,3,[4,5,[6,"SAME/IDENTICAL"]]]
));;     
console.log( ArrEQ( 
    [1,2,3,[4,5,[6,"DIFFERENT:APPLES" ]]],
    [1,2,3,[4,5,[6,"DIFFERENT:ORANGES"]]]
));;  

2

NESTED 배열 로 MULTIPLE 인수와 함께 작동 합니다.

//:Return true if all of the arrays equal.
//:Works with nested arrays.
function AllArrEQ(...arrays){
    for(var i = 0; i < (arrays.length-1); i++ ){
        var a1 = arrays[i+0];
        var a2 = arrays[i+1];
        var res =( 
            //:Are both elements arrays?
            Array.isArray(a1)&&Array.isArray(a2) 
            ?
            //:Yes: Compare Each Sub-Array:
            //:v==a1[i]
            a1.every((v,i)=>(AllArrEQ(v,a2[i])))
            :
            //:No: Simple Comparison:
            (a1===a2)
        );;
        if(!res){return false;}
    };;
    return( true );
};;

console.log( AllArrEQ( 
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
));; 

2
In a simple way uning stringify but at same time thinking in complex arrays:

**Simple arrays**:  
var a = [1,2,3,4];  
var b = [4,2,1,4];  
JSON.stringify(a.sort()) === JSON.stringify(b.sort()) // true  

**Complex arrays**:  
var a = [{id:5,name:'as'},{id:2,name:'bes'}];  
var b = [{id:2,name:'bes'},{id:5,name:'as'}];  
JSON.stringify(a.sort(function(a,b) {return a.id - b.id})) === JSON.stringify(b.sort(function(a,b) {return a.id - b.id})) // true  

**Or we can create a sort function**  

function sortX(a,b) {  
return a.id -b.id; //change for the necessary rules  
}  
JSON.stringify(a.sort(sortX)) === JSON.stringify(b.sort(sortX)) // true  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.