developer tip

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

copycodes 2020. 10. 4. 11:45
반응형

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


이 두 배열이 있습니다. 하나는 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');

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

아마도?


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

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

짧고 간단하고 예쁘다!


코드가 작동하지 않는 이유

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 (n) 시간을 수행 할 수 있습니다 . JS에서 사전은 단순히 키와 값이있는 객체입니다.

// assumes array elements are primitive types
function areArraysEqualSets(a1, a2) {
  let superSet = {};
  for (let i = 0; i < a1.length; i++) {
    const e = a1[i] + typeof a1[i];
    superSet[e] = 1;
  }

  for (let i = 0; i < a2.length; i++) {
    const e = a2[i] + typeof a2[i];
    if (!superSet[e]) {
      return false;
    }
    superSet[e] = 2;
  }

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

  return true;
}

이 함수는 기본 유형의 배열에서 작동하며 a1과 a2가 배열이라고 가정합니다.


Prototype Framework를 사용하는 경우 배열 intersect 메서드를 사용 하여 순서에 관계없이 동일한 지 확인할 수 있습니다.

var array1 = [1,2];
var array2 = [2,1];

if(array1.intersect(array2).length === array1.length) {
    alert("arrays are the same!");
}

I had simple integer values in a Game project
Had less number of values in each array, also, needed that original array untouched
So, I did the below, it worked fine. (Code edited to paste here)

var sourceArray = [1, 2, 3];
var targetArray = [3, 2, 1];

if (sourceArray.length !== targetArray.length) {
    // not equal
    // did something
    return false;
}

var newSortedSourceArray = sourceArray.slice().sort();
var newSortedTargetArray = targetArray.slice().sort();

if (newSortedSourceArray.toString() !== newSortedTargetArray.toString()) { // MAIN CHECK
    // not equal
    // did something
    return false;
}
else {
    // equal
    // did something
    // continued further below
}

// did some more work

return true;

Hope that helps.


Using ES6

We'll use Ramda's equals function, but instead we can use Lodash's or Underscore's isEqual:

const R = require('ramda');

const arraysHaveSameValues = (arr1, arr2) => R.equals( [...arr1].sort(), [...arr2].sort() )

Using the spread opporator, we avoid mutating the original arrays, and we keep our function pure.


kindly check this answer

var arr1= [12,18];
var arr2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17];
for(i=0;i<arr1.length;i++)
{
var array1=arr1[i];
for(j=0;j<arr2.length;j++)
{
    var array2=arr2[j];
    if(array1==array2)
    {
return true;
    }
}
}

If the items in the array are primitives (numbers or single characters), you can use a combination of comparing lengths, and using sets.

function equalArrayItems(arr1, arr2) {
  if (arr1.length !== arr2.length) return false
  const set1 = new Set(arr1)
  const set2 = new Set(arr2)
  const set3 = new Set(arr1, arr2)
  return set1.size === set3.size && set2.size === set3.size
}

Answering after long time but hope this will help somebody who looking for a simple solution and modern newbies.

Now we can achieve this using multiple libraries like lodash, underscore, etc. (These becomes part of the project nowadays due to simplicity, multiple features and high usage)

You can use intersection from lodash library.

_.intersection(['2-1', '1'], ['2-2', '3-1', '2-1']); 
// => ['2-1']

This will work for any data type..

참고URL : https://stackoverflow.com/questions/6229197/how-to-know-if-two-arrays-have-the-same-values

반응형