🌈 Array vs Set vs Map vs Object
자바스크립트에서 가장 많이 사용하는 내장 객체에는 배열(Array), 셋(Set), 맵(Map), 오브젝트(Object)가 있다.
이번 포스팅에서는 어떤 상황에서 가장 적절한 방법으로 사용할 수 있는지에 대해 작성하려고 한다.
1️⃣ 검색
2️⃣ 정렬
3️⃣ 값의 포함 여부
4️⃣ 중복되는 값의 제거
5️⃣ 특정값의 제거
6️⃣ 객체의 크기와 길이
👨💻 결론
1️⃣ 검색
◾ Array
// find를 이용한 객체 반환
let array = [
{id:1, name:'one'}
, {id:2, name:'two'}
];
array.find(obj => obj.id === 2); // {id: 2, name: 'two'}
// 특정 요소의 인덱스 반환
let array = ['one', 'two', 'three'];
array.indexOf("one"); // 0
◾ Object
// 인덱스 검색
let obj = [
{id:1, name:'one'}
, {id:2, name:'two'}
];
obj[1]; // {id: 2, name: 'two'}
◾ Set
Set에는 인덱스를 검색하거나 찾는 내장 함수가 없다. 따라서 배열로 변환 후 배열의 내장 함수를 사용한다.
// find를 이용한 객체 반환
const newSet = new Set([{1: 'one'}, {2: 'two'}, {3: 'three'}]);
[...newSet].find(object => object[2] === 'two'); // {2: 'two'}
// 특정 요소의 인덱스 반환
const newSet = new Set(['1','2','3']);
[...newSet].indexOf('2'); // 1
◾ Map
Map은 Key-Value의 구조를 갖고 있으며, Key는 문자열, 숫자, 객체, NaN이 될 수 있다.
또한, Key를 통해 Value를 반환받을 수 있다.
var map = new Map([[ 1, 'one' ],[ 2, 'two' ]]);
map.get(1) // 'one'
2️⃣ 정렬
◾ Array
Array의 sort 메서드를 사용할 때 unicode 유형에 따라 다른 동작을 수행할 수도 있다는 점을 기억해야 한다.
따라서 직접 로직을 작성하여 정렬시킬 줄 알아야 한다.
// 특수 문자가 없는 문자열 배열
const arr = [ "sex", "age", "job"];
arr.sort(); //["age", "job", "sex"]
// 숫자 배열
const arr = [ 30, 4, 29 , 19];
arr.sort((a, b) => a-b); // [4, 19, 29, 30]
// 문자열로 된 숫자의 배열
const arr = [ "30", "4", "29" , "19" ];
arr.sort((a, b) => a-b); // ["4", "19", "29", "30"]
// 숫자와 문자열 숫자가 혼합된 배열
const arr = [ 30, "4", 29 , "19" ];
arr.sort((a, b) => a-b); // ["4", "19", 29, 30]
// ASCII코드가 아닌 문자열 배열
const arr = ['réservé', 'cliché', 'adieu'];
arr.sort((a, b) => a.localeCompare(b)); // ['adieu', 'cliché','réservé']
// 객체 배열
const arr = [
{ key: 'Sharpe', value: 37 },
{ key: 'And', value: 45 },
{ key: 'The', value: -12 }
];
// key를 기준으로 정렬
arr.sort((a,b) => a['key'].localeCompare(b['key']));
// value를 기준으로 정렬
arr.sort((a,b) => a['value']-b['value']);
◾ Object
Object에는 정렬을 위해 내장된 메서드가 없지만, ES6의 객체는 내장 키 정렬이 실행된 후 생성된다.
// key가 숫자(숫자문자열)로 구성된 객체는 정렬된다.
const obj = { 30: 'dad', '4': 'kid', 19: 'teen', '100': 'grams'};
console.log(obj) //{4: "kid", 19: "teen", 30: "dad", 100: "grams"}
// Key가 문자(열)인 객체는 정렬되지 않는다.
const obj = { "b": "two", "a": "one", "c": "three" };
console.log(obj) // returns {b: "two", a: "one", c: "three"}
// Key가 숫자+문자(열)의 혼합으로 구성된 객체는 부분적으로 정렬된다.(숫자만 정렬됨)
const obj = { b: "one", 4: "kid", "30": "dad", 9: "son", a: "two" };
console.log(obj) // returns {4: "kid", 9: "son", 30: "dad", b: "one", a: "two"}
◾ Set
Set도 Object와 마찬가지로 정렬을 위해 내장된 메서드가 없다.
따라서 Set을 Array로 변환한 후 정렬하거나, entries메서드를 이용해 새로운 Set을 만들어 정렬할 수 있다.
// Set을 Array로 변환 및 정렬
const set = new Set(['b', 'a', 'c']);
[...set].sort(); // ['a', 'b', 'c']
// entries 메서드를 사용하여 정렬된 새 Set를 만들수도 있다.
const set = new Set(['b', 'a', 'c']);
const sortedSet = new Set([...set.entries()].map((entry) => entry[0]).sort());
// Set(3) {'a', 'b', 'c'}
◾ Map
Map도 Object와 마찬가지로 정렬을 위해 내장된 메서드가 없지만, Set과 유사한 방법으로 정렬할 수 있다.
// entries 메서드를 사용하여 정렬할 수 있다.
const map = new Map([["c", 'three'],["a", 'one'], ["b", 'two']]);
const sortedMap = new Map([...map.entries()].sort())
// Map(3) {"a" => "one", "b" => "three", "c" => "two"}
3️⃣ 값의 포함 여부
iterable 객체의 가장 중요한 기능 중 하나는 값의 포함 여부를 확인하는 것이다.
자바스크립트의 거의 모든 내장 객체에는 이를 위한 메서드가 있다.
◾ Array
// 선형 배열만을 고려한다.
const arr = [1, 2, 3];
arr.includes(1); // true
arr.includes('1'); // Type이 일치하지 않으면 false를 반환한다.
◾ Object
// Object의 경우 Key를 기준으로 포함여부를 찾는다.
const obj = { a: 1, b: 2, c: 3, 1: 'one' };
obj.hasOwnProperty('a'); // true
obj.hasOwnProperty(1); // true
obj.hasOwnProperty('1'); // true (hasOwnProperty 메서드는 Type을 체크하지 않는다.)
◾ Set
const set = new Set([1, 2, 3, 4, 5]);
set.has(4); // true
set.has('4'); // Type이 일치하지 않으면 false를 반환한다.
◾ Map
const map = new Map([[3, 'three'],["a", 'one'], ["b", 'two']]);
map.has('a'); // true
map.has(3); // true
map.has('3'); // Type이 일치하지 않으면 false를 반환한다.
🙋♂️ Array와 비교하였을 때 Object와 Set/Map은 O(1)에 가까운 성능을 낸다.
4️⃣ 중복되는 값의 제거
◾ Array
ES6에서 추가된 filter와 map을 이용하여 쉽게 중복되는 값을 제거할 수 있다.
// 선형 배열의 경우 Set을 이용해 중복을 제거할수있다.
const arr = [1, 2, 2, 4, 5, 5];
[...new Set(arr)]; // [1, 2, 4, 5]
// 객체의 경우에 Set을 통해 중복값을 제거할 수 없다.
const arr = [{a:1},{b:2},{a:1}];
[...new Set(arr)]; // [{a:1},{b:2},{a:1}]
// 따라서 ES6의 filter와 map을 이용하여 중복을 제거할 수 있다.
arr.filter((obj, index) => {
return arr.map(obj => obj['a']).indexOf(obj['a']) === index;
}); // [{a:1},{b:2}]
◾ Object
Object는 중복 키 값을 허용하지 않으며 이전 값은 새로운 값으로 덮어씌워진다.
const obj = { b: "one", a: "two", a: "three" };
console.log(obj); // {b: "one", a: "three"}
◾ Set
Set은 Array와 같은 선형 배열의 경우 중복을 허용하지 않지만 객체 배열을 전달할 경우 중복을 허용한다.
// 선형 배열
const set = new Set([1, 2, 2, 4, 5, 5]);
console.log(set); // {1, 2, 4, 5}
// 객체 배열
const set = new Set([{a:1},{b:2},{a:1}]);
console.log(set); // {{a:1},{b:2},{a:1}}
◾ Map
Map은 Object와 비슷하게 중복되는 키를 허용하지 않는다.
const map = new Map([[3, 'three'], [2, 'two'], [2, 'four']]);
console.log(map); // {3 => "three", 2 => "four"}
5️⃣ 특정값의 제거
◾ Array
Array는 특정 값을 제거하는 메서드가 없다. 그러나 아래와 같은 방법으로 제거할 수 있다.
const arr = [ 'a', 'b', 'c' ];
arr.filter(e => e !== 'c'); // [ 'a', 'b' ]
◾ Object
Object에도 특정 값을 제거하는 내장 메서드가 존재하지 않지만, delete를 사용하여 키를 삭제할 수 있다.
예시에서는 delete를 사용하였지만 실제 코드 작성 시에는 filter와 map을 통해 특정값을 제거하도록 하자.
// 권장하는 방법은 아니지만 delete를 사용하여 키를 제거할 수 있다.
const obj = { b: "one", a: "two" };
delete obj.a; // 키가 a인 값을 제거 후 true를 반환한다.
◾ Set
Set에는 특정 값을 제거하는 내장 메서드가 존재한다.
const set = new Set([1, 2, 4, 5]);
set.delete(4); // 4를 제거한 후 true를 반환한다.
set.delete('5'); // Type이 일치하지 않는경우 false를 반환한다.
◾ Map
Map에도 Set과 마찬가지로 특정 값을 제거하는 내장 메서드가 존재한다.
const map = new Map([[3, 'three'], [2, 'two']);
map.delete(3); // 키가 3인 값을 제거 후 true를 반환한다.
map.delete('2'); // Type이 일치하지 않는경우 false를 반환한다.
6️⃣ 객체의 크기와 길이
// Array에는 컬렉션 길이에 대한 속성값(length)이 존재한다.
['1', '2', '3'].length // 3
// Object에는 길이나 크기에 대한 속성값이 존재하지 않으므로 Keys배열을 이용하여 길이를 확인한다.
Object.keys({ b: 'one', a: 'two', c: 'three' }).length // 3
// Set과 Map은 크기에 대한 속성값이 존재한다.
new Set([{a:1},{b:2},{a:1}]).size // 3
new Map([[3, 'three'],['a', 'one'], ['b', 'two']]).size // 3
👨💻 결론
자바스크립트 내장 객체를 선택할 때 기억해야 할 몇 가지 예시와 특징을 알아보았다.
코드를 작성할 때 여러 객체를 혼합하여 사용할 수 있지만, 케이스에 가장 적합한 객체를 선택하여 사용할 수 있는 유연성을 가져야 할 것이다.
📌 참고사이트
Array vs Set vs Map vs Object — Real-time use cases in Javascript (ES6/ES7)
'Frontend > JavaScript' 카테고리의 다른 글
[JS] 자바스크립트 열거형(Enum) 구현하기 (0) | 2023.01.04 |
---|---|
[JS] ES-Lint 비활성화 하는 방법 (0) | 2023.01.01 |
[JS] innerHTML과 InsertAdjacentHTML 비교(DOM Element) (0) | 2022.08.22 |
[JS] 자바스크립트 this (1/2) (0) | 2022.06.08 |
[JS] 자바스크립트 this(2/2) (0) | 2022.06.08 |
최근댓글