상세 컨텐츠

본문 제목

자바스크립트는 왜 동일한 요소를 담고있는 배열끼리 비교해도 false 값이 나올까?

FrontEnd/Java Script

by 유후(yufu) 2023. 5. 5. 02:08

본문

반응형

안녕하세요. 이번 글에서는 자바스크립트의 객체, 배열 비교에 대해서 얘기해보려고 합니다. 혹시 자바스크립트를 사용하면서, 배열이 가지고 있는 요소들이 동일한지 비교하기 위해 동일비교연산자(==)를 사용해 보신 적 있으신가요? 그렇다면 저처럼 당황을 하셨을거라 생각하는데요. 저는 배열 비교를 하면서 true 값을 기대했지만, false 값이 나와 식은 땀을 흘렸던 기억이 아직도 생생하네요 😂 그럼 글 시작하겠습니다 -

배열 비교

어.. 어랏 이게 왜 안돼

자바스크립트에서 동일한 요소를 담고 있는 배열끼리 비교해도 false 값이 나오는 이유는, 배열이 객체이기 때문입니다. 자바스크립트에서는 변수에 객체를 할당하면 값을 저장하는 것이 아니라 객체의 참조를 저장합니다. , 배열은 물리적으로 다른 위치에 있는 메모리 공간을 차지하고 있는 것입니다. 따라서 개의 배열이 같은 요소를 가지고 있더라도, 실제로는 서로 다른 참조를 가지고 있기 때문에 비교를 하였을 false 값이 나오는 것입니다.

예를 들어, 다음과 같은 코드를 실행하면 false 반환됩니다:

const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
console.log(arr1 === arr2); // false

 

배열 요소 비교 방법

그럼 배열 요소들이 모두 동일하다면, 배열이 동일한지를 비교하려면 어떻게 해야 할까요? 이를 위해서는 배열의 내용을 비교하는 방법을 사용해야 합니다. 배열의 내용을 비교하는 방법은 여러 가지가 있습니다. 라이브러리를 사용하는 방법과 그렇지 않은 방법 모두를 알아보겠습니다.

1. for문을 사용하여 각 요소를 비교하는 방법

function areArraysEqual(array1, array2) {
  if (array1.length !== array2.length) {
    return false;
  }

  for (let i = 0; i < array1.length; i++) {
    if (array1[i] !== array2[i]) {
      return false;
    }
  }

  return true;
}

console.log(areArraysEqual(array1, array2)); // true

위의 코드는 배열의 길이를 먼저 비교한 , for문을 사용하여 요소를 비교하는 방법입니다. 방법은 간단하지만, 배열의 크기가 크면 성능이 저하될 있습니다.

2. 배열의 toString() 메서드를 사용하여 비교하는 방법

function areArraysEqual(array1, array2) {
  return array1.toString() === array2.toString();
}

console.log(areArraysEqual(array1, array2)); // true

 

위의 코드는 배열의 toString() 메서드를 사용하여 배열을 문자열로 변환한 , 문자열을 비교하는 방법입니다. 방법은 배열의 크기가 크더라도 성능이 좋지만, 배열 요소가 문자열일 경우 오동작할 가능성이 있습니다.

3. lodash 라이브러리의 isEqual() 함수를 사용하는 방법

3번째 방법은 lodash 라이브러리에서 제공하는 isEqual() 함수를 사용하는 방법입니다. isEqual() 함수는 재귀적으로 객체와 배열을 비교하는 기능을 제공하기 때문에, 배열 요소가 객체인 경우에도 정확하게 비교할 있습니다.

const _ = require('lodash');

const array1 = [1, 2, { a: 1, b: 2 }];
const array2 = [1, 2, { a: 1, b: 2 }];

console.log(_.isEqual(array1, array2)); // true

위의 코드는 lodash 라이브러리에서 제공하는 isEqual() 함수를 사용하여 배열을 비교하는 방법입니다. isEqual() 함수는 배열의 크기나 요소의 순서가 다르더라도, 배열의 내용이 동일하면 true 반환합니다. 또한, 객체와 배열의 비교도 가능하기 때문에, 배열 내부에 객체가 있는 경우에도 정확하게 비교할 있습니다.

4. Underscore

Underscore Lodash 비슷한 자바스크립트 유틸리티 라이브러리로서, 배열 비교 기능도 제공합니다. Underscore 사용하여 배열을 비교하는 방법은 다음과 같습니다.

const _ = require('underscore');

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

console.log(_.isEqual(arr1, arr2)); // false

Lodash 사용 방법이 거의 동일합니다. Underscore 역시 내부적으로 깊은 비교를 수행하므로, 배열의 중첩 요소까지 비교할 있습니다.

배열 참조 비교

만약 배열 요소의 값이 아닌 참조 값을 비교하고자 때는, 얕은 복사(shallow copy) 수행하여 새로운 배열을 만들어 비교해야 합니다. 이를 위해서는 spread operator Array.from() 메서드를 사용하여 새로운 배열을 만들고 비교하는 것이 일반적인 방법입니다.

아래와 같이 동일한 요소를 가진 개의 배열을 복사한 비교하면 true 반환합니다:

const arr1 = [1, 2, 3];
const arr2 = [...arr1];
console.log(arr1 === arr2); // false
console.log(arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index])); // true

 

배열 비교의 주의사항

배열 비교를 수행할 때 주의해야 할 몇 가지 사항이 있습니다.

1. 참조 비교와 값 비교

배열은 객체이므로, 배열의 비교는 참조 비교와 값 비교로 나뉩니다. 참조 비교는 두 배열이 같은 객체를 참조하고 있는지를 비교하는 것인 반면 값 비교는 두 배열이 같은 값으로 구성되어 있는지를 비교하는 것입니다. 예를 들어, 다음과 같은 두 개의 배열이 있다고 가정해봅시다.

let arr1 = [1, 2, 3];
let arr2 = [1, 2, 3];
let arr3 = arr1;

이 경우, arr1과 arr2는 값 비교에서 같다고 판단됩니다. 하지만 arr1과 arr3은 참조 비교에서 같다고 판단됩니다. 따라서 배열을 비교할 때는 어떤 비교 방식을 사용할 것인지 명확히 해야 합니다.

2. 중첩된 배열의 비교

배열 비교를 수행할 때, 배열 내에 중첩된 배열이 있는 경우에는 깊이(depth)에 주의해야 합니다. 예를 들어, 다음과 같은 두 개의 배열이 있다고 가정해봅시다.

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

이 경우, arr1과 arr2는 값 비교에서 같다고 판단됩니다. 하지만 중첩된 배열이 있을 경우, 깊이에 따라서 비교 결과가 달라질 수 있습니다. 예를 들어, 다음과 같은 두 개의 배열이 있다고 가정해봅시다.

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

경우, arr1 arr2 비교에서 다르다고 판단됩니다. 따라서 중첩된 배열이 있는 경우에는 깊이를 고려한 비교가 필요합니다.

 

마치며

이왜진스러운 자바스크립트의 객체, 배열 비교에 대해서 알아봤습니다. 배열 비교는 자바스크립트에서 매우 중요한 작업 하나입니다. 배열 비교를 수행할 때는 for문을 이용한 비교나, Lodash, Underscore, Ramda 등의 라이브러리를 이용한 비교 다양한 방법을 사용할 있습니다. 하지만 배열 비교는 참조 비교와 비교, 중첩된 배열 등에 주의해야 하며, 어떤 비교 방식을 사용할 것인지 명확히 해야 합니다. 이러한 주의사항을 숙지하면, 배열 비교를 효율적으로 수행할 있습니다.

자바스크립트 진짜 나한테 왜그래 이게 왜 진짜인건데

 

반응형

관련글 더보기