개발 도구 (Development Tools)/Sample Code

배열에서 원하는 객체만 삭제하는 방법

BiCute 2022. 10. 20. 08:00
반응형

 

배열에서 원하는 항목을 제거하고 싶은 경우가 꽤나 자주 발생하는데, 

그와 관련된 이런저런 내용을 간략히 적어봅니다.

 

 

 

예제 샘플

  users라는 배열에는 대충 아래와 같이 이름(userName), 나이(age)등 다양한 정보를 포함한 객체가 담겨져 있다.

[
    {
      "no": 1,
      "userName": "Terry",
      "age": 50,
      "gender": "male",
      "email": "atuny0@sohu.com",
      "userID": "atuny0",
      "birthDate": "2000-12-25",
      "image": "https://robohash.org/hicveldicta.png",
      "bloodType": "A−",
      "address": "1745 T Street Southeast",
      "city": "Washington",
      "postalCode": "20020"
    },
    {
      "no": 2,
      "userName": "Sheldon",
      "age": 28,
      "gender": "male",
      "email": "hbingley1@plala.or.jp",
      "userID": "hbingley1",
      "birthDate": "2003-08-02",
      "image": "https://robohash.org/doloremquesintcorrupti.png",
      "bloodType": "O+",
      "address": "6007 Applegate Lane",
      "city": "Louisville",
      "postalCode": "40219"
    },
    {
      "no": 3,
      "userName": "Terrill",
      "age": 38,
      "gender": "male",
      "email": "rshawe2@51.la",
      "userID": "rshawe2",
      "birthDate": "1992-12-30",
      "image": "https://robohash.org/consequunturautconsequatur.png",
      "bloodType": "A−",
      "address": "560 Penstock Drive",
      "city": "Grass Valley",
      "postalCode": "95945"
    },
    // ...
    ]

 

  위 데이터를 이용해서 아래와 같은 형식으로 구현했을 경우에 DELETE 버튼을 누른 항목만 제거 해보자.

 

 

#1. forEach

  forEach를 사용하여 배열을 순회하며 원하는 값을 가진 배열을 찾는다면 쉽게 해결이 가능하다.

  아래 샘플은 Vue 기준으로 작성.

// 01. 반복문을 이용하여 배열들을 나열한다.
// 02. DELETE 버튼을 누르면 해당 객체의 no값을 파라미터로 하여 함수를 실행한다
<template>
    <div v-for="(item, index) in users" :key="index">
        <div> No.{{ item.no }} - {{ item.userName }} </div>
        <button @click="deleteUser(item.no)">DELETE</button>
    </div>
</template>

//
<script>
export default {
	data(){
    	return{
        	users: ...유저데이터(생략)
        }
    },
    mehods: {
// 03. users의 배열을 돌며 각 item의 no와 파라미터로 받아온 userNo값이 같다면
// 해당하는 index 1개를 삭제하는 방법
        deleteUser(userNo) {
          this.users.forEach((item, index) => {
            if (item.no === userNo) this.users.splice(index, 1);
          });
        },    
    }
}
</script>

 

 

JavaScript 버전의 샘플코드

let data = [
  {no: 1, uuid: 'b5e705317d6d', name: '사과'},
  {no: 2, uuid: '876676485cdc', name: '이미지'},
  {no: 3, uuid: '8c1a124befbb', name: '체크 상자'},
  {no: 4, uuid: '41479a85aadb', name: '삭제대상'},
  {no: 5, uuid: '7daaee2f79e2', name: '서명란'},
  {no: 6, uuid: 'ca9f98b89939', name: '날짜/시간'},
];

function deleteItem(uuid) {
    data.forEach((item, index) => {
        if(item.uuid === uuid)
         data.splice(index, 1);
    })
}
                 
deleteItem('41479a85aadb');
console.log(data)

 

이렇게만 작성해도 충분히 의도한 방식대로 작동은 한다.

하지만, 저 배열이 10개, 20개가 아니라, 10,000개, 100,000개짜리 배열이라면...?

하나 삭제하기 위해 매번 몇만번씩 모든 배열을 순회해야 한다. 

10만개의 배열중 4번째에서 해당 결과를 찾아 삭제를 해도 의미없이 99,996번을 더 비교하고있는 샘이다.

 

그렇다면...

원하는 값을 찾았다면 빠져나오도록 만들어주자.

 

 

#2. some() / every()

  반복문이니 빠져나올땐 break를 적어주면 해결이 될거같지만, forEach에서는 break를 사용할 수 없다.

  이럴땐 some 또는 every 메서드를 사용해보자. 

  둘다 forEach처럼 배열을 순회하는데 조금씩 사용방법이 다르다

  (원래의 용도대로라면 some()은 판별 함수를 통해 배열안의 어떤 요소라도 참이라면 true를 뱉어내고,

  every()는 배열 안의 모든 요소가 판별 함수를 통과하는지를 확인 할 수 있는 메서드이다)

 

  some은 return 값이 true라면 break, false라면 continue가 되고,

  every는 return 값이 false라면 break, true라면 continue가 된다.

  글만 보면 복잡하지만 써보면 forEach위치에 some이나 every만 넣어주면 되니 어렵지 않다.

 

some 사용 예)

let data = [
  {no: 1, uuid: 'b5e705317d6d', name: '사과'},
  {no: 2, uuid: '876676485cdc', name: '이미지'},
  {no: 3, uuid: '8c1a124befbb', name: '체크 상자'},
  {no: 4, uuid: '41479a85aadb', name: '삭제대상'},
  {no: 5, uuid: '7daaee2f79e2', name: '서명란'},
  {no: 6, uuid: 'ca9f98b89939', name: '날짜/시간'},
];

function deleteItem(uuid) {
    data.some((item, index) => {
      console.log(index)
        if(item.uuid === uuid){
         data.splice(index, 1);
          return true;  // <-- some은 true일때 break
        }

    })
                 
deleteItem('876676485cdc');
console.log(data)

 

그렇다면 또 다른 방법은 없을까...?

 

 

#3. findIndex

  직접 해당하는 아이템의 인덱스값을 찾아서 배열에서 제거하는 방법도 있다.

  (결과적으론 거기서 거기니 편한대로 사용하면 된다)

  혹시 findIndex를 사용하는데 결과가 원하는대로 나오지 않는다면 매칭이 잘 되었는지 확인해보자.

  console.log로 return(여기선 index)를 찍어봤을때 -1이 나온다면 해당하는 값이 없다는 뜻이다.

let data = [
  {no: 1, uuid: 'b5e705317d6d', name: '사과'},
  {no: 2, uuid: '876676485cdc', name: '이미지'},
  {no: 3, uuid: '8c1a124befbb', name: '체크 상자'},
  {no: 4, uuid: '41479a85aadb', name: '삭제대상'},
  {no: 5, uuid: '7daaee2f79e2', name: '서명란'},
  {no: 6, uuid: 'ca9f98b89939', name: '날짜/시간'},
];

function deleteItem(input) {  
    const index = data.findIndex(function(item){
// 여기서 item은 각 객체이다.
// 받아온 값과 각 배열의 uuid값이 같다면 해당 값을 index에 넣어준다.
    return item.uuid === input
    });
    data.splice(index, 1);
}
                 
deleteItem('876676485cdc');
console.log(data)

 

 

 

반응형