본문 바로가기
Javascript

sort() 메서드로 상품 정렬 기능 만들기

by 즐코딩 2023. 2. 24.
반응형

sort() 메서드로 상품 정렬 기능 만들기



지난 포스팅에서는 서버에서 Data를 받아 온 후, 브라우저 화면에 반복문을 돌며 뿌려주는 것에 대해서 공부하고 정리해보았습니다. 프론트단 구성에서 굉장히 자주 사용되는 중요한 내용이니, 코딩까지는 직접 못하는 상태이더라도 해당 로직에 대해서는 꼭 이해를 해두시고 다음 단계로 넘어가실 것을 권장합니다.

서버에서 받은 데이터를 forEach() 이용해서 UI 반복 생성하기

 

서버에서 받은 데이터를 forEach() 이용해서 UI 반복 생성하기

서버에서 받은 데이터를 forEach() 이용해서 UI 반복 생성하기 이전까지 2~3개의 포스팅을 통해서, Javascript를 이용해서 동적으로 UI를 생성하는 과정을 정리해왔습니다. 기초적인 DOM 조작 및 Data 핸

kincoding.com




오늘은 이전 포스팅으로 뿌려진 내용을 정렬하는 방법을 살펴보고자 합니다.
즉, 1, 2, 3화 순서대로 표시되어 있는 것을

[역순-정렬]-버튼을-누르면-1화,-2화,-3화-순으로-정리된-것을
[역순 정렬] 버튼을 누르면 1화, 2화, 3화 순으로 정리된 것을


[역순 정렬] 버튼을 클릭하게 되면, 3화, 2화, 1화 순으로 표시되도록 하는 것입니다.

3화,-2화,-1화-순으로-역순-정렬을-해줍니다.
3화, 2화, 1화 순으로 역순 정렬을 해줍니다.

 

잠시만, JS 정렬 문법 살펴보고 가실께요! - sort() 메서드


정렬? 하면 떠 오르는 단어는 sort입니다. 그래서 Javascript에도 sort()라는 배열객체 메서드(=함수)가 이미 만들어져 있습니다. 그럼 한번 사용해보겠습니다.

const nums = [3, 6, 2, 5, 1];
nums.sort();
console.log(nums);  // [1, 2, 3, 5, 6]

원하던-대로-오름차순-정렬이-잘-된것-같습니다만...
원하던 대로 오름차순 정렬이 잘 된것 같습니다만...


우선 코드를 살펴보니, sort()는 배열 원본을 변경시켜준다는 것을 알 수 있습니다. sort()를 수행한 이후에 nums를 console.log()로 찍어보니 변경된 배열로 나타나죠?

근데, 정렬이 잘 되는 것 같군요! 그런데 말입니다... 아래 코드는 어떤 결과를 가져다 줄까요?

const nums = [3, 6, 20, 2, 5, 1];
nums.sort();
console.log(nums);  // [1, 2, 20, 3, 5, 6]

눈치-없이,-20이-중간에-끼어있습니다?
눈치 없이, 20이 중간에 끼어있습니다?


눈치 없이 숫자 20이 중간에 끼어 있습니다. 어디서 많이 본듯한 정렬결과죠?
맞습니다. 문자로 인식을 하고 정렬을 해서 20이 2와 3사이에 끼어 있는 것입니다.

그렇다면, 숫자로 정렬을 할 때는 JS에서 어떻게 해야할까요?

sort()메서드의 숫자 정렬


숫자 정렬을 할 때도 동일하게 sort() 메서드를 사용할 수 있습니다. 바로 아래처럼요.

const nums = [3, 6, 20, 2, 5, 1];
nums.sort(function (a, b) {
  return a - b;
});
console.log(nums); // [1, 2, 3, 5, 6, 20]

숫자-20이-제일-뒤로-잘-정렬되었습니다.
숫자 20이 제일 뒤로 잘 정렬되었습니다.


sort()를 사용할 때, 콜백함수를 인자로 넣는데, 그 콜백함수는 또 a, b 두개의 파라미터를 받고 있습니다.
그리고 a - b를 한 결과를 return 해주고 있습니다. 왜 이 따구로 써야 할까요?

자바스크립트 만든 사람(Brendan Eich)이 그렇게 쓰게 만들었으니까요. a - b 니까 뭔가 숫자가 나올 것도 한데, 사실 내부적으로는 눈에 안보이는 연산을 하고 있는 겁니다. a, b는 배열에 담긴 원소 2개를 의미합니다. 하나씩 다 가져다가 빼 보면서 크기 비교를 하고 있는 겁니다. 코드 중간에 a, b를 확인해보는 내용을 넣어서 확인해봅시다.

const nums = [3, 6, 20, 2, 5, 1];
nums.sort(function (a, b) {
  console.log(a, b);  //요걸 넣어서 뭐가 찍히는 지 살펴봅시다
  return a - b;
});
console.log(nums);

배열의-원소를-두-개씩-꺼내서-다-비교를-해보고-있습니다.
배열의 원소를 두 개씩 꺼내서 다 비교를 해보고 있습니다.


배열의 원소를 두 개씩 꺼내서 다 비교를 해보고 있죠?

nums.sort(function (a, b) {
return a - b;
});

위 식은, 배열에서 원소 2개를 꺼내서 빼기를 해본 후,
양수(+)값이 나오면 a를 배열의 오른쪽으로 보내고,
음수(-) 값이 나오면 b를 배열의 오른쪽으로 보냅니다.


아무튼 이런 식으로 sort() 메서드는 동작하도록 자바스크립트 만든 사람이 만들어 뒀어요. 뭔가 겁나 불편해 보이죠?
하지만 그렇게 만든 데는 뭐 다 이유가 있는 거겠죠?(만드는 김에 좀 더 편하게 좀 만들지....)

자, 그럼 여기서 눈치게임 문제 하나! 역순으로 정렬하려면 어떻게 하면 좋을까요?


버튼 UI 만들기


자바스크립트의 sort()메서드에 대해서 알아보았으니, 본론으로 들어가봅시다.

지난 포스팅 소스에다가, 부트스트랩 버튼을 하나 추가하도록 해줍니다. 처음 보는 my-5 클래스는 margin-top과 margin-bottom을 동시에 조절하는 클래스, 즉 y 축으로 margin을 조정하는 값입니다.

<div class="container text-center mt-5">
  <h1 class="mb-5">ZomFLIX</h1>
  <div class="row">
    <!-- 생성한 카드가 표시될 위치 -->
  </div>
  <button class="btn btn-primary my-5" id="btn-reverse">역순 정렬</button>
</div>

부트스트랩-버튼을-하나-만들어-넣습니다.
부트스트랩 버튼을 하나 만들어 넣습니다.


이제 저 버튼을 클릭해주면, sort()를 사용해서 정렬을 하면 되겠군요.

서버에서 넘겨준 자료는 다음과 같다고 했습니다. 어떤 녀석으로 정렬 기준을 삼으면 좋을까요?

id값에-친절하게-일련번호로-숫자가-있군요
id값에 친절하게 일련번호로 숫자가 있군요


제목 안에서 숫자를 뽑아도 가능하겠지만, 친절하게도 id값을 가지고 있으니 그걸 활용하면 될 것 같습니다.
그런데, 데이터가 단순 배열이 아니라, 배열 안에 객체를 원소로 가지고 있는 형태입니다.(아씨.. 복잡해보여!)



버튼에 JS 코딩으로 기능 만들기


객체에서 data를 뽑는 방법만 한번 더 상기하고, 한번에 생각하려 하지 말고 아래 코드를 한 스텝씩 살펴봅시다.

document.querySelector("#btn-reverse").addEventListener("click", function () {
  zombies.sort(function (a, b) {
    return b.id - a.id;    //  b - a 는 역순, 객체의 id값 가져와서 빼기
  });
});


// 위 코드를 jQuery로 바꿔보면 ↓

$("#btn-reverse").on("click", function () {
  zombies.sort(function (a, b) {
    return b.id - a.id;    //  b - a 는 역순, 객체의 id값 가져와서 빼기
  });
});


일단 버튼에 이벤트 리스너를 달아둔 위 코드를 통해서, 역순 정렬은 일어 나겠죠? 못 미더우면 하단에 console.log(zombies)를 찍어서 확인해보세요.

zombies-배열은-역순으로-바뀌었습니다.
zombies 배열은 역순으로 바뀌었습니다.


배열은 역순이 된 것 같은데, 버튼을 눌러도 브라우저 화면에는 아무 일도 일어나지 않습니다. 왜 일까요?
맞습니다. 배열만 역순으로 바뀐 상태이지, 화면의 UI에는 어떠한 조작 명령이 없기 때문입니다.

따라서, row아래다 붙일 것이기 때문에 row에 담겨진(nested) 내용을 싹~! 지워주는 코딩을 한 후, 다시 row에 zombies 배열이 갖고 있는 데이터를 뿌려주면 되는 거겠죠?

지난 포스팅에서 forEach()로 배열의 내용을 뽑아서 화면에 뿌려주기 위해 작성했던 코드를 가져다 써봅시다.

document.querySelector("#btn-reverse").addEventListener("click", function () {
  zombies.sort(function (a, b) {
    return b.id - a.id;
  });
  
  document.querySelector(".row").innerHTML = "";   // 기존 내용을 공백으로 처리 = 싹 비워줌
  zombies.forEach(function (data, i) {      // 배열 원소를 가져다 화면에 뿌려주던 코드
    const template = `
    <div class="col">
        <div class="card" style="width: 18rem">
          <img src="${zombies[i].thumb}" class="card-img-top" alt="..." />
          <div class="card-body">
            <h5 class="card-title">${zombies[i].title}</h5>
            <p class="card-text">러닝타임 : ${zombies[i].time} 분</p>
          </div>
        </div>
      </div>
    `;
    $(".row").append(template);
  });
});

[역순-정렬]-버튼을-클릭해주면&#44;-3화&#44;-2화&#44;-1화-순으로-역순-정렬을-해줍니다.
[역순 정렬] 버튼을 클릭해주면, 3화, 2화, 1화 순으로 역순 정렬을 해줍니다.


버튼을 클릭해보면, 잘 동작합니다. 목표달성!!

이제 쇼핑몰 같은데서, 낮은 가격순으로 상품을 정렬하는 것 따위는 손 쉽게 만들 수 있겠습니다. 별거 아니죠?


최종 소스 코드


코드 분량이 많아 단계가 좀 복잡하게 느껴질 수 있으니, 아래에 전체 코드를 첨부합니다.
찬찬히 살펴보시고 이리저리 바꿔 가면서 테스트를 진행해보면 좋은 공부과제가 될 것입니다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ZomFLIX</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
  </head>
  <body class="bg-dark-subtle">
    <div class="container text-center mt-5">
      <h1 class="mb-5">ZomFLIX</h1>
      <div class="row">
        <!-- 생성한 카드가 표시될 위치 -->
      </div>
      <button class="btn btn-primary my-5" id="btn-reverse">역순 정렬</button>
    </div>

    <script>
      const zombies = [
        { id: 0, thumb: "zombie1.jpg", title: "좀비 1화", time: 48 },
        { id: 1, thumb: "zombie2.jpg", title: "좀비 2화", time: 59 },
        { id: 2, thumb: "zombie3.jpg", title: "좀비 3화", time: 55 },
      ];

      document.querySelector("#btn-reverse").addEventListener("click", function () {
        zombies.sort(function (a, b) {
          return b.id - a.id;
        });
        document.querySelector(".row").innerHTML = "";
        zombies.forEach(function (data, i) {
          const template = `
    <div class="col">
        <div class="card" style="width: 18rem">
          <img src="${zombies[i].thumb}" class="card-img-top" alt="..." />
          <div class="card-body">
            <h5 class="card-title">${zombies[i].title}</h5>
            <p class="card-text">러닝타임 : ${zombies[i].time} 분</p>
          </div>
        </div>
      </div>
    `;
          $(".row").append(template);
        });
      });

      zombies.forEach(function (data, i) {
        const template = `
    <div class="col">
        <div class="card" style="width: 18rem">
          <img src="${zombies[i].thumb}" class="card-img-top" alt="..." />
          <div class="card-body">
            <h5 class="card-title">${zombies[i].title}</h5>
            <p class="card-text">러닝타임 : ${zombies[i].time} 분</p>
          </div>
        </div>
      </div>
    `;
        $(".row").append(template);
      });
    </script>
  </body>
</html>



마치며


위 소스는 Vanilla JS랑 jQuery랑 마구 섞여 있습니다. 게다가 화면에 뿌려주는 코드도 중복이 되고 있구요.
중복되는 코드는 함수(function)으로 정의해서 사용할 때 마다 호출해서 사용해주는 방식으로 코드를 정리한다면 더 좋은 코드가 될 것입니다.

우리가 사용자였을 때, 단순히 버튼 하나 눌러서 상품을 가격순으로 정리하던 그 기능이, 이렇게 만들어져서 사용되는 것이었구나! 하는 이해를 갖는 것이 이번 포스팅의 목표였습니다. 어떻게 보면 초보자가 한번에 구현하기에는 다소 벽이 좀 높은 초보고급기술(?) 이라고도 이야기해볼 수 있겠습니다만, 익숙해지고 나면 간단한 거죠.

참, 이렇게 JS를 이용해서 Client-side에서 정렬 기능을 만들었지만, 서버에서도 Database에 질의(Query)를 역정렬해주세요~ 라고 날린 후 받아서 클라이언트로 보내주는 Server-side 방식도 있답니다.

오늘도 즐거운 코딩하세요!
즐거운 코딩생활, 즐코딩.
KINcoding.com


https://app.kincoding.com/

 

WANTED MBTI

MBTI Girl Match a Lovely Girl Friend 당신과 어울리는 사랑스런 여친을 매칭해드립니다.

app.kincoding.com

 

반응형

댓글