영광의 시대!/2022 개발자의 품격 부트캠프 1기

[개발자의품격][부트캠프][1기][8차시] JavaScript 주요 포인트 #4 | 내장 객체 - Array 객체

DandyNow 2022. 2. 2. 17:55
728x90
반응형

JavaScript 주요 포인트 #4

내장 객체 - Array 객체

Array 객체는 실무에서 많이 사용하는 매우 중요한 객체이다.

 


 

join

<script>
  let brands = ["애플", "구글", "메타", "아마존", "네이버", "카카오"];

  // join()은 배열의 문자열을 하나의 문자열로 결합하며, 실무에서 많이 사용한다.
  console.log(brands.join(", ")); // 구글, 메타, 아마존, 네이버, 카카오
</script>

join은 배열의 문자열을 하나의 문자열로 결합하는 기능으로서 실무에서 많이 사용한다. 아래의 코드는 좀 더 구체적인 예이다.

<button onclick="doSearch()">조회</button>
<table>
  <thead>
    <tr>
      <th>음료</th>
      <th>가격</th>
    </tr>
  </thead>
  <tbody id="table1Tbody"></tbody>
</table>
<script>
  function doSearch() {
    const productList = [
      // 음료 리스트
      {
        name: "솔의눈",
        price: 700,
      },
      {
        name: "커피",
        price: 700,
      },
      {
        name: "파워레이드",
        price: 1200,
      },
      {
        name: "오렌지",
        price: 1000,
      },
      {
        name: "보리차",
        price: 1200,
      },
      {
        name: "밀키스",
        price: 800,
      },
    ];
  }

  // += 연산자를 이용한 문자열 결합
  // let h = "";
  // for (const product of productList) {
  //   h += "<tr>";
  //   h += "<td>" + product.name + "</td>";
  //   h += "<td>" + product.price + "</td>";
  //   h += "</tr>";
  // }
  // document.getElementById("table1Tbody").innerHTML = h;

  // 많은 데이터를 다룰 때는 문자열 결합을 사용하지는 않고, 배열에 push하는 방식을 이용한다.
  let h = [];
  for (const product of productList) {
    h.push("<tr>");
    h.push("<td>" + product.name + "</td>");
    h.push("<td>" + product.price + "</td>");
    h.push("</tr>");
  }

  // for문 결과 배열 h의 값은 ['<tr>', '<td>솔의눈</td>', '<td>700</td>', '</tr>', '<tr>', '<td>커피</td>', '<td>700</td>', '</tr>', '<tr>', '<td>파워레이드</td>', '<td>1200</td>', '</tr>', '<tr>', '<td>오렌지</td>', '<td>1000</td>', '</tr>', '<tr>', '<td>보리차</td>', '<td>1200</td>', '</tr>', '<tr>', '<td>밀키스</td>', '<td>800</td>', '</tr>']
  // join 함수를 이용해 문자열로 결합하여 화면에 출력할 html 코드를 완성한다.
  document.getElementById("table1Tbody").innerHTML = h.join("");
</script>

많은 데이터를 다룰 때는 배열에 push한 후 join 함수를 이용해 문자열로 결합니다. 결합되는 양이 적을 때는 +=을 이용한 문자열 결합이 빠르지만, DB에서 데이터를 불러오는 경우라면 상황이 달라진다. 몇천에서 몇만 건이 넘어가는 데이터는 배열을 이용하는 것이 성능면에서 훨씬 유리하다. [그림 1]은 위 코드의 실행 결과이다. 조회 버튼을 누르면 데이터가 표시된다.

 

[그림 1] 배열과 push 함수 사용

 


 

pop / shift

<script>
  let brands = ["애플", "구글", "메타", "아마존", "네이버", "카카오"];

  // pop() 배열의 마지막 인덱스의 요소를 제거하고 반환
  console.log(brands.pop()); // 카카오

  // shift() 배열의 0번 인덱스의 요소를 제거하고 반환(실무에서는 shift를 pop보다 훨씬 많이 사용함)
  console.log(brands.shift()); // 애플
  
  // shift는 큐를 만들어 사용할 때 유용하다. 사용자의 요청이 들어올때마다 처리해야하는 값이 계속 배열의 마지막 인덱스에 push되고, 동시에 0번 인덱스의 값을 처리할때 쓰인다.
  // let eventQueue = [];
  // eventQueue.shift();
</script>

실무에서는 shift를 pop 보다 더 많이 사용한다. 주로 서버로부터 대량의 고객 연락처(또는 이메일 주소)를 가져와 문자 메시지(또는 이메일)를 발송하는 기능을 구현할 때 이용한다. 또한 큐를 다룰 때 유용하다.

 


 

unshift

<script>
  let brands = ["애플", "구글", "메타", "아마존", "네이버", "카카오"];
  brands.unshift("삼성전자");
  console.log(brands); // ['삼성전자', '애플', '구글', '메타', '아마존', '네이버', '카카오']
</script>

unshift는 배열의 0번 인덱스에 요소를 추가하고 배열 길이를 반환한다.

<body>
  <select name="" id="city"></select>
  // 이 코드에서는 라인 "추가, 삭제" 버튼의 기능을 구현하지 않았지만, 자바스크립트를 이용해 리스트 박스의 라인을 추가, 삭제하는 기능을 구현할 수 있다.
  <button>라인추가</button>
  <button>라인삭제</button>
  <script>
    // unshift 함수는 실무에서 리스트 박스를 이용해 검색하는 기능을 만들때 주로 사용한다.
    function loadCity(needAll) {
      let cities = [
        { code: "02", title: "서울" },
        { code: "21", title: "부산" },
        { code: "064", title: "제주" },
      ];

      let h = [];
      
      // 배열 h에 리스트 cities의 각 오브젝트를 push
      for (const city of cities) {
        h.push(
          '<option value="' + city.code + '">' + city.title + "</option>"
        );
      }
      
      // needAll이 참일 때 배열 h의 0번 인덱스에 요소를 추가한다. 해당 값은 리스트 박스의 최상단에 표시된다.
      if (needAll) {
        h.unshift('<option value="">==전체==</option>');
       }

      document.getElementById("city").innerHTML = h.join("");
    }

    loadCity(1);
  </script>
</body>

unshift 함수는 실무에서 리스트 박스를 이용해 검색하는 기능을 만들때 주로 사용한다. 개발자들 중 자바스크립트 내장 함수를 잘 알고 있으면 쉽게 해결할 수 있는 문제를 어렵게 해결하는 경우가 많은데 리스트 박스의 구현도 그중 하나이다. 위 코드를 보면 for 문을 통해 리스트 cities 내에 있는 각 오브젝트가 배열 h에 push된다. 그 후 unshift 함수에 의해 배열 h의 0번 인덱스에 값이 추가된다. 해당 값은 [그림 2]와 같이 리스트 박스의 최상단에 위치하게 된다. unshift 함수를 "라인 추가" 버튼과 연결하면 리스트 박스의 최상단에 새로운 라인을 추가하는 버튼을 구현할 수 있다.

 

[그림 2] unshift 함수에 의해 최상단에 추가된 "==전체=="

 


 

splice

<script>
  let brands = ["애플", "구글", "메타", "아마존", "네이버", "카카오"];
  brands.splice(1, 0, "리턴벨류", "더그레잇"); // 1번 파라미터는 새로운 요소를 추가할 인덱스 번호, 2번 파라미터는 1번 파라미터 인덱스 번호에서 부터 삭제할 요소 수, 나머지 파라미터는 추가할 요소
  console.log(brands); // ['애플', '리턴벨류', '더그레잇', '구글', '메타', '아마존', '네이버', '카카오']
</script>

splice 함수는 실무에서 마치 엑셀에서 행이나 열을 삽입하듯이 처리할때 유용하다. 실무에서 splice를 사용하면 쉽게 구현할 수 있는 기능을 if 문을 이용해 하드 코딩하는 경우가 있다. 좋은 개발자는 내장 함수를 잘 이해하고 있어야 할 뿐만 아니라 응용할 수 있어야 한다.

 


 

concat

<script>
  // concat
  let arr1 = ["A", "B"];
  let arr2 = ["C", "D"];
  let arr3 = ["E", "F", "G"];
  let arr4 = arr1.concat(arr2, arr3);
  console.log(arr4); // ['A', 'B', 'C', 'D', 'E', 'F', 'G']
  
  // 실무에서는 이 방법을 더 많이 사용한다.
  let arr5 = [...arr1, ...arr2, ...arr3];
  console.log(arr5); // ['A', 'B', 'C', 'D', 'E', 'F', 'G']
</script>

2개 이상의 배열을 하나로 결합한다. 실무에서는 concat보다는 리스트 안에서 ...을 더 많이 사용한다.

 


 

slice

<script>
  let arr = ["A", "B", "C", "D", "E", "F", "G"];
  
  // slice(시작인덱스, 종료인덱스)
  console.log(arr.slice(1, 2)); // ['B']
</script>

문자열 slice와 같은 개념이다. 멘토님은 실무에서 그다지 사용하지 않았다고 한다.

 


 

sort

<script>
  let brands = ["애플", "구글", "메타", "아마존", "네이버", "카카오"];
  
  // 가나다순 정렬
  console.log(brands.sort()); // ['구글', '네이버', '메타', '아마존', '애플', '카카오']

  let points = [40, 100, 1, 5, 25, 10];
  console.log(points.sort()); // [1, 10, 100, 25, 40, 5], sort는 숫자를 문자열로 이해하고 정렬한다.
</script>

sort 함수는 실무에서 많이 사용한다. 기본적으로 가나다순으로 정렬한다. 정수도 문자열로 인식하고 정렬하기 때문에 주의해야 한다.

<script>
  let points = [40, 100, 1, 5, 25, 10];

  // 내장함수 sort의 원리를 이용해 정수를 오름차순(또는 내림차순) 정렬할 수 있다.
  // sort 원리: 비교하는 값의 차가 양수이면 위치 바꾸고, 음수이면 그대로 둔다.
  function numberSortAsc(a, b) {
    // a = 40, b = 100 -> -60(음수 값이면 위치를 바꾸지 않음)
    // a = 100, b = 1 -> 99(양수 값이면 위치를 바꿈)
    // ~ 계속 돌면서 처리. 더 이상 변경되지 않으면 종료
    return a - b; // 오름차순
  }
  console.log(points.sort(numberSortAsc)); // [1, 5, 10, 25, 40, 100]

  function numberSortDes(a, b) {
    // a = 40, b = 100 -> 60(양수 값이면 위치를 바꿈)
    // a = 40, b = 1 -> -39(음수 값이면 위치를 바꾸지 않음)
    // ~ 계속 돌면서 처리. 더 이상 변경되지 않으면 종료.
    return b - a; // 내림차순
  }
  console.log(points.sort(numberSortDes)); // [100, 40, 25, 10, 5, 1]
</script>

정수로 구성된 배열을 정렬하는 방법은 위의 코드와 같다. sort 함수의 원리를 이용해 정수를 오름차순(또는 내림차순) 정렬할 수 있다. sort 원리는 이터러블(iterable) 객체를 0번 인덱스부터 시작해 두 요소를 비교하여 값의 차가 양수이면 위치 바꾸고, 음수이면 그대로 둔다.

<script>
  const productList = [
    // 음료 리스트
    {
      name: "솔의눈",
      price: 700,
    },
    {
      name: "커피",
      price: 700,
    },
    {
      name: "파워레이드",
      price: 1200,
    },
    {
      name: "오렌지",
      price: 1000,
    },
    {
      name: "가봉",
      price: 1000,
    },
    {
      name: "보리차",
      price: 1200,
    },
    {
      name: "밀키스",
      price: 800,
    },
  ];

  // 오브젝트의 name을 기준으로 정렬
  // function objectSort(a, b) {
  //   if (a.name > b.name) return 1;
  //   else if (a.name < b.name) return -1;
  //   else return 0;
  // }
  // console.log(productList.sort(objectSort)); // 결과는 [그림 3] 왼쪽 참조

  // 오브젝트의 price를 기준으로 정렬
  // function priceSort(a, b) {
  //   if (a.price > b.price) return 1;
  //   else if (a.price < b.price) return -1;
  //   else return 0;
  // }
  // console.log(productList.sort(priceSort)); // 결과는 [그림 3] 중간 참조
  
  // 오브젝트의 price 기준으로 정렬하고, price가 같으면 name 기준으로 정렬
  function twoFieldSort(a, b) {
    if (a.price > b.price) return 1;
    else if (a.price < b.price) return -1;
    else {
      if (a.name > b.name) return 1;
      else if (a.name < b.name) return -1;
      else return 0;
    }
  }
  console.log(productList.sort(twoFieldSort)); // 결과는 [그림 3] 오른쪽 참조

</script>

sort의 양수, 음수 여부에 따른 위치 바꿈의 원리를 이용해 리스트 내 오브젝트를 정렬할 수 있다.

 

[그림 3] 오름차순 정렬로서 왼쪽부터 name, price, price(1순위) name(2순위) 기준이다.

 


 

filter

<script>
  const productList = [
    // 음료 리스트
    {
      name: "솔의눈",
      price: 700,
    },
    {
      name: "커피",
      price: 700,
    },
    {
      name: "파워레이드",
      price: 1200,
    },
    {
      name: "오렌지",
      price: 1000,
    },
    {
      name: "가봉",
      price: 1000,
    },
    {
      name: "보리차",
      price: 1200,
    },
    {
      name: "밀키스",
      price: 800,
    },
  ];

  // if문 사용
  newProductList = [];
  const inputCoin = 1000; // 1000원 이하만 필터링
  for (const product of productList) {
    if (product.price <= inputCoin) {
      newProductList.push(product);
    }
  }
  console.log(newProductList);

  // filter 사용 1
  function doFilter(product) {
    // if (product.price <= inputCoin) {
    //   return true;
    // } else {
    //   return false;
    // }
    return product.price <= inputCoin ? true : false;
  }
  newProductList = productList.filter(doFilter);
  console.log(newProductList);

  // filter 사용 2
  newProductList = productList.filter(function (p) {
    return p.price <= inputCoin ? true : false;
  });
  console.log(newProductList);

  // filter 사용 3 - 화살표 함수 사용 1
  newProductList = productList.filter((p) =>
    p.price <= inputCoin ? true : false
  );
  console.log(newProductList);

  // filter 사용 4 - 화살표 함수 사용 2
  console.log(productList.filter((p) => p.price <= inputCoin));
</script>

filter 함수는 실무에서 조회시 매우 많이 사용한다. 특히 화살표 함수와 함께 사용하는 경우를 눈여겨보자!

 


 

map

<script>
  let userList = [
    {
      firstName: "재석",
      lastName: "유",
      email: "yu@gmail.com",
    },
    {
      firstName: "종국",
      lastName: "김",
      email: "kim@gmail.com",
    },
    {
      firstName: "흥국",
      lastName: "김",
      email: "kim@gmail.com",
    },
    {
      firstName: "세찬",
      lastName: "양",
      email: "yang@gmail.com",
    },
    {
      firstName: "석진",
      lastName: "지",
      email: "ji@gmail.com",
    },
  ];

  function newUserMap(user) {
    return {
      //   firstName: user.firstName,
      //   lastName: user.lastName,
      email: user.email,
      fullName: user.lastName + user.firstName,
    };
  }

  let userList2 = userList.map(newUserMap);
  console.log(userList2);
</script>

map 함수는 원하는 오브젝트를 새롭게 만들 때 유용하다. 서버에서 데이터를 받아올 때 map을 이용해 원하는 데이터를 가공해 가져올 수 있다. 쿼리를 사용하는 경우도 있지만 데이터 패킷 부담을 줄이는 등 이 방법이 효율적일 수 있다. 

 


 

reduce

<script>
  points = [80, 90, 95, 78, 88, 100, 92];
  let sum = points.reduce(function (
    accumulator, // 누적값
    currentValue, // 현재 배열 요소
    currentIndex, // 현재 배열 인덱스 번호
    arr // 전체 배열
  ) {
    return accumulator + currentValue;
    // return currentIndex; //6
    // return arr; // [80, 90, 95, 78, 88, 100, 92]
  }, 0); //누적값의 처음값 0
  console.log(sum); // 623

  const productList = [
    // 음료 리스트
    {
      name: "솔의눈",
      price: 700,
    },
    {
      name: "커피",
      price: 700,
    },
    {
      name: "파워레이드",
      price: 1200,
    },
    {
      name: "오렌지",
      price: 1000,
    },
    {
      name: "가봉",
      price: 1000,
    },
    {
      name: "보리차",
      price: 1200,
    },
    {
      name: "밀키스",
      price: 800,
    },
  ];

  // price 합계
  let sum1 = productList.reduce(function (
    // 파라미터명은 변경해도 무관, 순서는 지켜야 함
    accumulator, // 누적값
    currentValue, // 현재 배열 요소, 일반적으로 누적값과 현재 배열 요소만 사용함
    currentIndex, //현재 배열 인덱스 번호
    arr // 전체 배열
  ) {
    return accumulator + currentValue.price;
  }, 0);
  console.log(sum1); // 6600

  // 1000상위인 price 합계
  let sum2 = productList.reduce(function (total, product) {
    if (product.price > 1000) {
      return total + product.price;
    } else {
      return total;
    }
    // return total + product.price;
  }, 0);
  console.log(sum2); // 2400

  // 리스트 내 문자열 누적
  let alphabets = ["A", "B", "C"];
  let alphabetString = alphabets.reduce(function (alpha, c) {
    return alpha + c;
  }, ""); // ""는 누적값의 처음 문자열 값
  console.log(alphabetString); // ABC
</script>

reduce를 이용해 배열의 합계를 쉽게 구할 수 있다. 배열에 담긴 데이터를 하나씩 순회하며 callback 함수의 실행 값을 누적하여 결괏값을 반환한다. 멘토님의 경우에는 문자열 누적보다는 숫자의 합계를 구할 때 주로 사용했다고 한다.

 

728x90
반응형