본문 바로가기
자바스크립트

[JAVASCRIPT] 배열 vs 객체, 배열보다 객체를 써야 하는 경우, 배열을 객체로 바꾸는 방법(array to object)

by jaewooojung 2024. 1. 3.

JAVASCRIPT


배열 vs 객체

애플리케이션에서 데이터를 다룰 때에는 데이터의 용도에 맞게 적절한 자료구조를 사용해야 합니다. 배열과 객체는 모두 대량의 데이터를 다룰 때 활용할 수 있는 자료구조이며, (사실 자바스크립트에서는 배열도 객체입니다만) 내장 메서드를 활용하면 간단하게 양쪽 간에 형태를 서로 변환할 수 있습니다.

 

형태를 변환해주어야 하는 경우의 예로는 외부에서 가져온 데이터의 구조가 애플리케이션과 궁합이 맞지 않는 경우, 자체적으로 구현한 자료구조라고 하더라도 형식을 변환해 줌으로써 순간적인 성능 향상의 이점을 얻을 수 있는 경우 등이 있습니다.
 
배열을 객체로 바꿔줘야 하는 경우
배열 내의 특정 요소에 접근하기 위해서는 우선 모든 요소들을 순회해야합니다. 이때 배열 내의 각 요소를 특정할 수 있는 수단은 index밖에 없기 때문에 해당하는 index를 모르는 상태라면 필연적으로 첫번째부터 배열의 요소를 순회해야 한다는 단점이 있습니다(BFS, DFS 등의 알고리즘은 본 글의 주제를 벗어나므로 다루지 않겠습니다).

 

또한 index를 알고 있는 경우라고 하더라도 그 index를 뽑아내기 위해서 사전에 이미 배열의 요소들을 순회한 셈이므로 동일한 성능상의 손해가 있었다고 볼 수 있습니다.


이러한 단점 때문에 길이가 크고 각 요소로의 접근이 잦은 배열이라면 객체로 변환한 후에 사용하는 것이 좋습니다. 

 

 

예시

코드를 통해서 살펴보겠습니다.
배열과 객체 각각 내부의 데이터에 접근하면서 수행시간을 측정하겠습니다.

1. 배열

let arr = [];
for (let i = 1; i <= 10000000; i++) {
  arr.push({
    id: i,
    name: `사람 ${i}번`
  });
}
console.log(arr);
/*
[
  { id: 1, name: '사람 1번' },
  { id: 2, name: '사람 2번' },
  { id: 3, name: '사람 3번' },
  { id: 4, name: '사람 4번' },
  { id: 5, name: '사람 5번' },
  { id: 6, name: '사람 6번' },
  { id: 7, name: '사람 7번' },
  { id: 8, name: '사람 8번' },
  { id: 9, name: '사람 9번' },
  ...
  { id: 10000000, name: '사람 10000000번' }
]
*/

id와 name property를 갖고 있는 객체의 배열입니다. 길이는 1000만으로 설정했습니다.

 

위 배열에서 id가 800만 인 객체에 접근하고 수행시간을 측정해 보겠습니다.

console.time("search time - array");
const target = arr.find(value => value.id === 8000000);
console.timeEnd("search time - array");

 

5번의 실행결과는 아래와 같습니다. 실행환경은 node입니다.

search time - array: 99.548ms
search time - array: 96.498ms
search time - array: 91.824ms
search time - array: 95.571ms
search time - array: 100.882ms

평균적으로 97ms 소요되었습니다.

 

2. 객체

let obj = {};
for (let i = 1; i <= 10000000; i++) {
  obj[i] = {
    id: i,
    name: `사람 ${i}번`
  };
}
/*
{
  '1': { id: 1, name: '사람 1번' },
  '2': { id: 2, name: '사람 2번' },
  '3': { id: 3, name: '사람 3번' },
  '4': { id: 4, name: '사람 4번' },
  '5': { id: 5, name: '사람 5번' },
  '6': { id: 6, name: '사람 6번' },
  '7': { id: 7, name: '사람 7번' },
  '8': { id: 8, name: '사람 8번' },
  '9': { id: 9, name: '사람 9번' },
  ...
  '10000000': { id: 10000000, name: '사람 10000000번' }
}
*/

 

id와 name property를 갖고 있는 객체들을 이번에는 각 id를 key로 하는 내부 객체의 형태로 구현하였습니다.

 

동일하게 id가 800만 인 내부 객체에 접근하고 수행시간을 측정해 보겠습니다.

console.time("search time - object");
const target = obj["8000000"];
console.timeEnd("search time - object");

 

5번의 실행결과는 아래와 같습니다.

search time - object: 0.265ms
search time - object: 0.224ms
search time - object: 0.253ms
search time - object: 0.218ms
search time - object: 0.243ms

 

평균적으로 0.24ms 소요되었습니다.

 

결과

배열 97ms 복잡도 O(n)
객체 0.24ms 복잡도 O(1)

 

객체에서 내부 객체를 찾는 경우에는 모든 객체의 주소가 key값으로 특정되어 있기 때문에 실행 즉시 메모리에서 값을 찾아옵니다(O(1)).

 

따라서 배열에서 자료를 지속적으로 찾아야 하는 경우에는 배열을 객체로 전환한 후 작업을 진행하면 시간복잡도 O(1)를 유지할 수 있습니다. 

3. 배열을 객체로 변환하는 방법

아래는 배열을 객체로 변환하는 다양한 예시들입니다.

const obj = {};
for (let i = 0; i < arr.length; i++) {
  obj[arr[i].id] = arr[i];
}
const obj = {};
arr.forEach(value => (obj[value.id] = value));
const obj = arr.reduce((obj, cur) => {
obj[cur.id] = cur;
  return obj;
}, {});
const obj = Object.assign({}, ...arr.map(value => ({ [value["id"]]: value })));

 


https://medium.com/dailyjs/rewriting-javascript-converting-an-array-of-objects-to-an-object-ec579cafbfc7

 

Rewriting Javascript: Converting an Array of Objects to an Object.

Accessing data in an object is always preferable compared too traversing an array to find a value.

medium.com

 



        
답변을 생성하고 있어요.