ProgramingTip

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

bestdevel 2020. 9. 28. 09:41
반응형

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


두 배열을 비교하고 싶습니다. 이상적으로는 처음입니다. 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 인코딩은 각 배열을 수행하지만 각 값을 반복 할 필요가 있고 배열을 더 빠르고 "더 나은"방법이 있습니까?


배열을 비교하는 배열을 반복하고 모든 값을 비교합니다.

어레이 비교 :

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

" 하지만 말할없습니다. " 라고 말할 수 있습니다 . 그러면 루프가 모두 점에 유의해야합니다. 배열을 공유로 변환하는 첫 번째 재귀 루프와 두 노드를 비교하는 두 번째 순환 루프. 따라서이 방법 은 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을 비교하는 데 사용됩니다. 복잡한 내용을 비교하고 페이지이 답 보시면 superlong function 입니다.
이 작업을 수행 한 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]) {
...

두 기능 모두에 대한 작은 테스트 도구를 만들었습니다 .

개체 : indexOf중첩 배열contains

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


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

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

Rr, ECMAScript 6 / CoffeeScript / TypeScript with Arrow 함수 :

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

(참고 : 여기서 '스칼라'는를 사용하여 직접 비교할 수있는 값 을 의미합니다 ===.. 따라서 참조로 숫자, 문자열, 객체, 함수로 참조 비교 연산자에, 대한 자세한 내용 은 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


저는 Underscore 라이브러리를 배열 / 객체 객체 코딩 프로젝트에 사용하는 것을 좋아합니다 ... 배열이나 Lodash에서 다음과 같이 어울립니다.

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

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

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

이 오브젝트로 변환 a1하고 a2그들의 비교가 될 수 있습니다. 위의 답변 중 하나에 많은 정렬 알고리즘을 사용하므로 대부분의 경우 순서가 중요합니다.

더 이상 표현을 비교하는 것이 점이라고 표현을 비교한다는 점입니다. 정확히 원하는 것이 아닐 수도 있습니다.


"동일하다"는 의미가 명확하지 않습니다. 예를 들어, 배열 a과 그 아래 b가 동일하고 (중첩 배열에주의)?

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

실용적인 방법

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

Tomáš는 솔루션이 빠르다고 말할 수 있습니다. 중첩 여부에 관계없이 모든 어레이에서 작동하는 올인원 솔루션을 시도합니다. 사실, 그것은 입력으로 배열하는 것을 받아들이고 여전히 "유효한"을 제공하려고합니다.


제네릭은 보 완성을 제공합니다.

내 대답은 문제에 다르게 접근 할 것입니다. arrayCompare배열을 단계별로 진행하는 것과 관련된 일반적인 절차 부터 시작하겠습니다 . 거기에서, 우리는 같은 우리의 다른 기본적인 비교 기능을 구축 할 것입니다 arrayEqualarrayDeepEqual

// 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두 개의 입력 배열 xsys. 대부분의 경우 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다른 데이터 유형 (배열)의 맥락에서 1 차 비교기를 활용하는 고차 함수로서의 역할을 강조합니다 .


실제로 비교

대신 arrayLooseEquala ==사용하여 쉽게 정의 할 수 있습니다 . 이제 1( '1'숫자 )를 (문자열) 과 겸 때 결과는 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있는지 확인하는 사용자 정의 비교를 사용 a하고 b배열됩니다. 즉, 다시 적용 arrayDeepCompare, 명명 비교 ab사용자 지정 비교기 ( f). 이를 통해 구현 요소를 비교하는 방법과는 심층 비교 동작을 사용할 수 있습니다. 즉, 쇼, 위의 예처럼, 우리는 깊은 사용하여 바로 수 있습니다 equal, looseEqual또는 기타 비교기는 우리가합니다.

arrayDeepCompare카레 이므로 앞의 예에서했던 것처럼 부분적으로 적용 할 수 있습니다.

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

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

필자는 필요 에 따라 배열에 대해 얕거나 깊은 비교를 명시 적으로 선택할 수 있기 때문에 Tomáš의 솔루션에 비해 이미 명확한 개선 사항 입니다.


개체 비교 (예)

이제 배열이나 준비가 있다면 어떨까요? object-의 각 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비교기를 꿈꿀 수도 있습니다 ! 아이들이 정규를 얼마나 좋아하는지 알고 있습니다.

가장 빠른가요? 아니. 그러나 둘 중 하나 일 필요는 없습니다. 속도가 우리 코드의 유일한 품질을 측정하는 데 사용되는 측정 항목이라면 정말 훌륭한 코드가 많이 버려 질입니다. 이것이 바로 이것이 접근 방식을 The Practical Way 라고 부르는 이유 입니다. 아니면 좀 더 공정하게, A Practical Way. 이 답변은 다른 답변과 깔때 실용적이라고 말하는 것이 아니기 때문에 답변에 적합합니다. 객관적으로 사실입니다. 우리는 추론하기 매우 쉬운 코드가 거의없이 높은 수준의 실용성을 얻었습니다. 다른 코드는 우리가 말할 수 없었습니다.

이것이 귀하에게 "올바른"솔루션이 검증 되었습니까? 그것은 당신 이 일입니다. 그리고 아무도 당신을 위해 그렇게 할 수 없습니다. 당신의 필요가 무엇인지 당신만이 알고 있습니다. 거의 모든 경우에 저는 영리하고 빠른 종류보다 간단하고 실용적이며 다재다능한 코드를 중요하게 생각합니다. 당신이 중요하게 생각하는 것이 다를 수 있으므로 자신에게 맞는 것을 선택하십시오.


편집하다

나의 오래된 대답은 arrayEqual절차로 분해하는 데 더 작은 것을 두었습니다 . 이것은 흥미로운 연습이지만이 문제에 접근하는 가장 좋은 (가장 실용적인) 방법은 아닙니다. 관심이 상세한 내역을 볼 수 있습니다.


원래 질문의 정신으로 :

두 배열을 비교하고 싶습니다. 이상적으로는 것으로 . 화려 하지 않고 동일하면 참이고 거짓 거짓입니다.

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

반면 (67 %) 팀 아래로

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

모든 (69 %) 사용자

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

DEI로 감소 (74 %)

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

Gaizka Allende & vivek의 가입toString (78 %)

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

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

절반 toString (90 %) by Victor Palomo

a1 == a2.toString();

radtek의 stringify (100 %)

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

참고 배열은 단일 차원 배열을 분류하는 가정 아래의 예. .length공통 벤치 마크에 대한 비교가 제거되었습니다 ( a1.length === a2.length제안 사항에 추가 하면 ~ 10 % 성능 향상을 얻을 수 있음). 각각의 속도와 한계를 알고있는 자신에게 가장 솔루션을 선택하십시오.

관련없는 메모 : 사람들이 질문에 대한 완벽하게 합법적 인 답변에 대해 반대표 버튼에서 모든 방아쇠에 만족하는 John Waynes를 얻는 것을 보는 것은 흥미 롭습니다.


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/


여기에는 많은 생각이 대답 도움이 될 것입니다.

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

의 구조가 배열 어떻게 보일지에, 대한 질문에는 명시되어 있지 않으므로 배열에 중첩 배열이나 object-가 없다는 것을 확실히 알고 난 웬지 - (나에게 일어났습니다. 답변) 위의 코드가 작동합니다.

무슨 일이 벌어지는 지 우리는 다양한 연산자 (...)를 사용하여 두 배열을 연결 한 다음 Set을 사용하여이를 제거합니다. 일단 당신은 당신은 크기를 사용할 수 있습니다, 세 배열이 모두 같은 크기를 가지고 있다면 당신은 갈 수 있습니다.

이 대답은 또한 요소의 순서를 무시합니다. 내가 말했듯이 정확한 상황이 나에게 일어 났고 같은 상황에있는 누군가가 여기에 올 수 있습니다 (내가 한 것처럼).


편집 1.

Dmitry Grinko의 질문에 대한 답변 : "왜 여기서 스프레드 연산자 (...)를 사용 했습니까? -... new Set? 작동하지 않습니다."

이 코드를 고려하십시오.

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

그것이 차이입니다. 전자는 나에게 세트를 줄 짜고, 그 세트의 크기를 얻을 수있을 때도 작동 할 것입니다. 그러나 후자는 나에게 필요한 배열을 제공합니다. 이 해상도에 더 직접적입니다.


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

숫자 또는 확장의 두 배열 만있는 경우 빠른 한 줄입니다.

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

다음은 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)
}

mocha에 대한 몇 가지 테스트 케이스 :

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

차이 어설 션 라이브러리 와 함께 모카같은 테스트-frame 워크를 사용하는 경우 깊은 동등성을 사용 하여 배열을 비교할 수 있습니다.

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

배열의 적용에 동일한 요소가있는 경우에만 사실을 반환해야합니다.


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

Herer의 내 솔루션 :

/**
 * 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가 손상되었습니다.)

대부분의 경우 대부분의 경우 대부분의 경우 대부분의 경우 대부분의 경우 대부분의 경우 사용됩니다. 배열 레코드 배열에 대한 가장 빠른 비교 방법 일 것입니다.


제 경우에는 비교 배열에 숫자와 숫자 만 포함됩니다. 이 함수는 배열에 배열 요소가 포함되어 보여 보여줍니다.

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

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

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

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/


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)

코드가 거의없는 또 다른 접근 방식 ( Array reduceArray 포함 사용 ) :

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검사는 한 배열의 요소 집합이 다른 배열의 하위 집합이 아닌지 확인합니다.

  • 감속기는 하나의 배열을 찾아보고 다른 배열의 각 항목을 검색하는 데 사용합니다. 하나의 항목이 감소 함수는 반환합니다 false.

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

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

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


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

재귀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"]]]
));;  

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

나는 일반 믿는와 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;
    }

}

누군가를 도울 수 있기를 바랍니다.


이 펼쳐지는 배열, 배열 및 다차원 배열을 비교합니다.

function compare(a,b){
     var primitive=['string','number','boolean'];
     if(primitive.indexOf(typeof a)!==-1 && primitive.indexOf(typeof a)===primitive.indexOf(typeof b))return a===b;
     if(typeof a!==typeof b || a.length!==b.length)return false;
     for(i in a){
          if(!compare(a[i],b[i]))return false;
     }
     return true;
}

첫 번째 줄은 기본 유형인지 확인합니다. 두 매개 변수를 비교합니다.

만나라면. 반복을 반복하고 모든 요소를 ​​반복적으로 확인합니다.

용법 :

var a=[1,2,[1,2]];
var b=[1,2,[1,2]];
var isEqual=compare(a,b);  //true

이 함수는 임의의 모양과 차원의 두 배열을 비교합니다.

function equals(a1, a2) {

    if (!Array.isArray(a1) || !Array.isArray(a2)) {
        throw new Error("Arguments to function equals(a1, a2) must be arrays.");
    }

    if (a1.length !== a2.length) {
        return false;
    }

    for (var i=0; i<a1.length; i++) {
        if (Array.isArray(a1[i]) && Array.isArray(a2[i])) {
            if (equals(a1[i], a2[i])) {
                continue;
            } else {
                return false;
            }
        } else {
            if (a1[i] !== a2[i]) {
                return false;
            }
        }
    }

    return true;
}

[a]에서 모두 선택하고 [b]에서 모두 반복 : 결과 : 1, 5

var a = [1,4,5,9];
var b = [1,6,7,5];

for (i = 0; i < a.length; i++) {
    for (z = 0; z < a.length; z++) {
        if (a[i] === b[z]) {
            console.log(b[z]); // if match > console.log it 
        }
    }
}

나는 배열을 결합하고 사용을 만듭니다. 이 예제보다 복잡한 시나리오의 경우 다른 구분 기호를 사용할 수 있습니다.

var a1 = [1,2,3];
var a2 = [1,2,3];
if (a1.length !== a2.length) {
   console.log('a1 and a2 are not equal')
}else if(a1.join(':') === a2.join(':')){
   console.log('a1 and a2 are equal')
}else{
   console.log('a1 and a2 are not equal')
}

간단한 접근 방식 :

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

참고 URL : https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript

반응형