배열에서 특정한 값을 모두 지워야 하는 경우, filter나 map을 사용하면 편하지만, 간혹 참조값을 유지해야 하는 경우가 있다. 예를 들어 뷰의 컴포지션 API에서는 reactive를 사용해 Proxy를 만든 배열은 참조가 변하면 반응형을 잃어버린다.
그래서 이번에는 참조값을 유지하면서 특정 값을 지우는 방법을 다루었다.
['a', 'b', 'c', 'a', 'd', 'c', 'a']; 이 배열에서 'a'만 지우고 싶은 경우, 필터를 사용하면:
const data = ['a', 'b', 'c', 'a', 'd', 'c', 'a'];
const filtered = data.filter((v) => v === 'a');
console.log(filtered); // ['b', 'c', 'd', 'c'];
이처럼 filter를 사용해서 원하는 배열을 간단하게 만들 수 있다.
하지만 새로운 배열을 만들지 않고, 기존 배열의 원소들을 지우려면 조금 복잡하다. 지워야 할 원소들의 인덱스를 알아야하고, 반복문을 통해 인덱스에 해당하는 원소를 지워야하는데, 앞번호를 지우면 순서가 당겨져서 엉뚱한 원소가 지워지니, 뒷번호 부터 지워야한다.
다음과 같은 순서로 구현한다.
1. 특정값('a')의 index를 모두 찾아 'a'의 인덱스 값을 가지고 있는 배열을 만든다. 'a'가 아니면 -1을 리턴한다. (map)
2. -1을 모두 지워준다. (filter)
3. 내림차순으로 뒤집어서 인덱스의 배열을 만든다. (reverse)
4. 인덱스의 배열을 반복해서 'a'를 지운다. (forEach)
const data = ['a', 'b', 'c', 'a', 'd', 'c', 'a'];
data
.map((v, i) => (v === 'a' ? i : -1))
.filter((item) => item !== -1)
.reverse()
.forEach((i) => {
data.splice(i, 1);
});
console.log(data); // ['b', 'c', 'd', 'c']
의도한 것은 아니지만 어쩌다 보니 map, filter, forEach를 모두 사용했다.
이제 적절히 함수로 만들어서 원하는 곳 어디서든 배열을 유지하면서 특정값을 지울 수 있다.
function removeAll(array, target) {
array
.map((v, i) => (v === target ? i : -1))
.filter((item) => item !== -1)
.reverse()
.forEach((i) => {
array.splice(i, 1);
});
}
const data = ['a', 'b', 'c', 'a', 'd', 'c', 'a'];
removeAll(data, 'c');
console.log(data); // ['a', 'b', 'a', 'd', 'a']
removeAll(data, 'a');
console.log(data); // ['b', 'd']
'front > js' 카테고리의 다른 글
자바스크립트 캘린더 만들기 (0) | 2022.09.02 |
---|---|
[javascript] 반복하고 싶을 때 사용하는 함수 (0) | 2022.08.31 |
[js] Memory Management (0) | 2022.08.02 |
[js] Arrow function expressions (1) | 2022.08.01 |
[javascript] falsy (0) | 2022.07.26 |
댓글