javascript

배열의 중복 제거

Bittersweet- 2022. 6. 23. 11:31
728x90

필터(Filter)로 배열 중복 제거

filter()를 이용해서 조건에 맞는 요소만을 반환받는 방식으로 중복 요소 없는 배열을 만들 수 있다.

filter는 배열 요소의 선택 조건을 직접 정할 수 있기 때문에 중복 제거가 아니어도 다양한 조건에 맞는 배열을 얻을 수 있다.

const arr = ['Ryan', 'Amy', 'Ted', 'Lily', 'Ryan', 'Rick'];
const arrUnique = arr.filter((val, idx) => {
  return arr.indexOf(val) === idx; // 값이 처음 나오는 배열 인덱스와 현재 인덱스가 같으면 포함
});

console.log(arrUnique); // ['Ryan', 'Amy', 'Ted', 'Lily', 'Rick]

* indexOf()

배열에서 지정된 요소를 찾을 수 있는 첫번째 인덱스를 반환하고 존재하지 않으면 -1을 반환한다.

arr.indexOf(searchElement[, fromIndex]);

searchElement: 배열에서 찾을 요소

fromIndex: 검색을 시작할 색인

 

맵(Map)으로 배열 중복 제거

맵은 키-값의 쌍으로 이루어진 요소를 가지는 객체이다. 키는 중복될 수 없기 때문에 이 특성을 이용해 배열 요소를 키(Key)로 해서 맵이 데이터를 넣은 후, 객체 메서드인 keys()를 이용해 키 값만을 매열로 가져오는 식으로 중복 없는 배열을 생성

const arr = ['Ryan', 'Amy', 'Ted', 'Lily', 'Ryan', 'Rick'];
const objUnique ={}; // 중복없는 배열 요소만 담은 객체

arr.forEach(el => {
  objUnique[el] = true; // {Ryan: true, Amy: true, Ted: true, Lily: true, Rick: true}
});

const arrUnique = Object.keys(objUnique); // 객체 키만 모아서 배열로 반환
console.log(arrUnique); // ['Ryan', 'Amy', 'Ted', 'Lily', 'Rick']

* keys()

주어진 객체의 속성 이름들(keys)을 일반적인 반복문과 동일한 순서로 순회되는 열거할 수 있는 배열로 반환한다.

Object.keys(obj);

obj : 열거할 수 있는 속성 이름들을 반환받는 객체

 

셋(Set)과 확산 연산자로 배열 중복 제거

셋(Set)은 객체에서 값이 없고 키만 있는 것으로 이해할 수 있다.

셋 객체 생성자는 배열을 인자로 받아 중복이 없는 셋 객체로 반환하는 특징이 있다.

중복있는 배열 ➡ 셋 ➡ 확산 연산자로 펼침 ➡ 배열로 생성

위의 과정을 거쳐 중복없는 배열을 만들 수 있다.

const arr = ['Ryan', 'Amy', 'Ted', 'Lily', 'Ryan', 'Rick'];
const arrUnique = [...new Set(arr)];
console.log(arrUnique); // ['Ryan', 'Amy', 'Ted', 'Lily', 'Rick'];

1행의 코드로 배열의 중복을 없앨 수 있기 때문에 단순히 배열의 중복을 없애는 것이 목적이면 이 방법이 가장 좋은 방법이다.

 


객체가 요소인 배열의 중복 요소 제거

배열 요소인 객체의 동일성은 객체의 값이 모두 동일한 것을 같은 객체로 구분한다.

 

 

필터(Filter)로 객체 배열의 중복 제거

앞서 사용했던 indexOf() 메서드는 인자로 넘긴 값이 나오는 첫번째 인덱스를 반환하므로, 객체가 요소인 배열에서는 객체의 내부 값을 비교해야 하기 때문에 findIndex()의 인자로 객체의 값(들)을 비교하는 함수를 넘겨서 첫번째 값이 일치하는 객체의 배열 인덱스를 가져와야 한다.

const arr = [{name: 'Ryan', company: 'kakao'}, {name: 'Amy', company: 'naver'}, {name: 'Amy', company: 'naver'}];
const arrUnique = arr.filter((character, idx, arr) => {
  return arr.findIndex((item) => item.name === character.name && item.company === character.compay) === idx
});
console.log(arrUnique); // [{name: 'Ryan', company: 'kakao'}, {name: 'Amy', company: 'naver'}]

 

* findIndex()

주어진 판별 함수를 만족하는 배열의 첫번째 요소에 대한 인덱스를 반환한다. 만족하는 요소가 없으면 -1을 반환.

arr.findIndex(callback(element[, index [, array]]) [, thisArg])

callback: 3개의 인수를 취하여 배열의 각 값에 대해 실행할 함수

element: 배열에서 처리중인 현재 요소

index: 배열에서 처리 중인 현재 요소의 인덱스

array: findIndex 함수가 호출된 배열

thisArg: 선택사항. 콜백을 실행할 때 this로 사용할 객체

 

맵(Map)으로 객체 배열의 중복 제거

맵에 항목을 추가하는 키(Key)는 배열 요소인 객체를 문자열화(JSON.stringfy)해서 객체의 키와 값이 모두 같으면 같은 키가 되도록 한다.

맵의 값에는  배열의 객체를 그대로 저장해서 나중에 map.value()메서드로 객체들만 빠르게 가져와 배열로 만들도록 한다.

const arr = [{name: 'Ryan', company: 'kakao'}, {name: 'Amy', company: 'naver'}, {name: 'Amy', company: 'naver'}];
const map = new Map(); // 맵 성성
for(const el of arr) {
  map.set(JSON.stringfy(el), el); // name, company가 모두 같은 요소는 제외한 맵 생성
}
const arrUnique = [...map.value()];
console.log(arrUnique);

* JSON.stringfy()

Javascript 값이나 객체를 JSON 문자열로 변환한다. 선택적으로 replacer를 함수로 전달할 경우, 변환 전 값을 변형할 수 있고, 배열로 전달할 경우 지정된 속성만 결과에 포함한다.

JSON.stringfy(value[, replacer[, space]]);

value: JSON 문자열로 변환할 값

replacer(optional): 문자열화 동작 방식을 변경하는 함수, 혹은 JSON 문자열에 포함될 값 객체의 속성들을 선택하기 위한 화이트리스트(whitelist)로 쓰이는 String과 Number 객체들의 배열. 이 값이 null이거나 제공되지 않으면, 객체의 모든 속성들이 JSON 문자열 결과에 포함된다.

space(optional): 가독성을 목적으로 JSON 문자열 출력에 공백을 삽입하는데 사용되는 String 또는 Number 객체.

'javascript' 카테고리의 다른 글

Part 1. Promise란? (작동 방식)  (0) 2022.07.14
[ES6] Spread Operator(...)  (0) 2022.07.12
정규식 모음  (0) 2022.06.03
RegEX 정규 표현식(Regular Expression)  (0) 2022.06.03
[array] reduce() 사용법 및 예제  (0) 2022.04.14