findIndex
특정 배열에서 중복 객체를 제외하는 많은 방법 중
주관적인 견해로 가장 간결하게 처리할 수 있는 방법으로
findIndex를 활용하는 방식을 채택하여 실제 프로젝트에
적용한적이 있다.
findIndex매서드는 iterable한(반복 가능한) 객체에서
사용 가능한 매서드로 해당 객체를 0번째 요소부터
순회하며 매개변수내에서 true를 반환하게 되면
해당 요소의 index를 반환하는 매서드이다.
사용예시
const array = [{id:1, title: "test"}, {id:2, title: "test"}, {id:3, title: "test"}, ];
// id가 2인 객체의 인덱스를 반환
const findSecondId = array.findIndex((value) => value.id === 2);
console.log(findSecondId); // 1
이런 방식으로 특정 조건을 만족하게 되면 true를 반환하게 되고
findIndex는 true를 감지하면 순회를 멈추고 해당 데이터의 index를
반환하게 된다.
어떻게 findIndex로 중복 객체를 제거 할까?
순회의 프로세스를 순차적으로 이해한다면
비교적 간단하게 접근하여 적용할 수 있다.
실질적인 데이터베이스에 저장된 데이터들은
각각 고유값(id)을 가지고 있기 때문에 이를 통해서
중복 객체를 제거할 수 있다.
꼭 고유 id가 아니더라도 중복되는 데이터를 타겟으로
filter와 findIndex를 활용한다면 쉽게 가공할 수 있다.
- 예시코드
// 데이터 중 title이 "제목입니다." 인 객체는 createAt, title, id 모두 동일하다.
const data = [
{ id: 1, title: "textTitle.", createAt: 1235 },
{ id: 2, title: "제목입니다.", createAt: 1236 },
{ id: 2, title: "제목입니다.", createAt: 1236 },
{ id: 4, title: "newTitle.", createAt: 1238 },
{ id: 5, title: "allNewTitle.", createAt: 12359 },
];
// data 깊은 복사
const data2 = JSON.parse(JSON.stringify(data));
// id를 비교한 경우
const filteredById = data.filter((obj, idx) =>
(data.findIndex(obj2 => obj.id === obj2.id)) === (idx)
)
console.log(filteredById);
/*
[
{ id: 1, title: "textTitle.", createAt: 1235 },
{ id: 2, title: "제목입니다.", createAt: 1236 },
{ id: 4, title: "newTitle.", createAt: 1238 },
{ id: 5, title: "allNewTitle.", createAt: 12359 },
]
*/
// createAt를 비교한 경우
const filteredByCreateAt = data2.filter((obj, idx) =>
(data2.findIndex(obj2 => obj.createAt === obj2.createAt)) === (idx)
)
console.log(filteredByCreateAt);
/*
[
{ id: 1, title: "textTitle.", createAt: 1235 },
{ id: 2, title: "제목입니다.", createAt: 1236 },
{ id: 4, title: "newTitle.", createAt: 1238 },
{ id: 5, title: "allNewTitle.", createAt: 12359 },
]
*/
왜 중복이 제거되는걸까?
원리는 아주아주 심플하다.
배열 내의 특정 데이터가 유일한 경우에는 해당 데이터를 가진
데이터의 index 또한 유일해야만 한다.
하지만 같은 데이터가 존재한다면 index만 유일한 값이 되고
특정 데이터는 중복된 데이터를 가지게 된다.
그렇기 때문에 배열에서 반드시 유일할 수 밖에 없는
index값을 비교할 수 있도록 findIndex와 filter의 index를
활용하면 중복되는 특정 값을 가진 객체를 제외시킬 수 있다.
findIndex는 index 0부터 탐색을 시작하고 해당 조건이 맞는 순간
순회를 멈추고 해당 index를 반환하기 때문에 순회 도중
같은 데이터가 발견되면 서로 index가 달라지기 때문에
filter의 조건인 currentIndex === findIndex 가 false를
반환하게 되어 결국 중복된 데이터는 제외하고 반환하게
되기 때문이다.
마치며...
간혹 개발을 하다보면 이론적으로는 알고 있지만 막상 코드로 구현하고자 할 때 이상하리 만치 고민하게 되는 경우가 종종 있는 것 같다. 이번의 경우도 그랬다. 분명 어려운 것은 아니지만 딱히 활용할만한 상황이 없어서 였는지 설계할 때 고민을 꽤 했던 것 같다. 이론적으로 알고 있더라도 결국 직접 문제를 직면하고 해결하기 위해 설계를 떠올려보고 구상해보는 것이
더 깊은 이해도를 가질 수 있고 내 것으로 만들 수 있는 것 같다. 기술이든 개념이든 내가 설명할 수 있을 정도의 이해도를 갖춰야만 활용할 수 있다는 것을 깨달았다. 앞으로도 내가 아는 것을 설명할 수 있는 사람이 되자.
'Frontend > JavaScript' 카테고리의 다른 글
[ Javascript ES6 ] 변수 값 교환하기 (2) | 2024.01.01 |
---|---|
[ Javascript - Operator ] 자바스크립트 연산자 (0) | 2023.02.05 |
[ Javascript - Array ] 배열 (2) | 2023.02.04 |
[ Javascript - Object ] 객체 (0) | 2023.02.02 |