[javascript] 'string+number ' 문자열 정렬(추가: Array<object> key 기준 정렬)

하태현·2022년 1월 19일
1

javascript

목록 보기
21/23
const str = ['bbb', 'aaa', 'ccc'];
const num = [2, 10, 5, 1];
const strNum = ['a10', 'a2', 'a1', 'a12', 'j5', 'j10', 'j2', 'j1', 'j13', 'j19'];

str.sort(); // [ 'aaa', 'bbb', 'ccc' ]
num.sort(); // [ 1, 10, 2, 5 ]
strNum.sort(); // [ 'a1', 'a10', 'a12', 'a2', 'j1', 'j10', 'j13', 'j19', 'j2', 'j5' ]

위의 string배열, number배열, string+number(string)배열을 sort함수를 이용해 정렬을 해보니
결과가 예상한 대로 나오지 않는다. 그 이유는 sort 함수가 문자열 비교이기 때문이다.

num.sort((a, b) => a - b); // [ 1, 2, 5, 10 ]

숫자를 정렬 하기 위해선 위와 같은 방법으로 정렬이 가능하다.

하지만 string과 number가 합쳐진 문자열은 어떻게 정렬할 것인가.

문자+숫자는 javascript에선 문자로 인식한다.

이를 해결하기 위한 내장함수가 이미 존재 한다.
MDN localeCompare

// 오름차순
const getSingleValueAsc = (arr) => {
  return arr.sort(function (a, b) {
    return a.localeCompare(b, undefined, {
      numeric: true,
      sensitivity: 'base',
    });
  });
};
// 내림차순
const getSingleValueDesc = (arr) => {
  return arr.sort(function (a, b) {
    return b.localeCompare(a, undefined, {
      numeric: true,
      sensitivity: 'base',
    });
  });
};
console.log(getSingleValueAsc(strNum));
// [ 'a1', 'a2', 'a10', 'a12', 'j1', 'j2', 'j5', 'j10', 'j13', 'j19' ]
console.log(getSingleValueDesc(strNum));
// [ 'j19', 'j13', 'j10', 'j5', 'j2', 'j1', 'a12', 'a10', 'a2', 'a1' ]

하지만 배열에 단일 값만 들어오지 않을 수 있다.
Array<object>형태의 배열을 내부 요소(객체) 해당하는 key 기준으로 정렬하고 싶다면 아래와 같이 할수 있다.

const valueOfKeyArr = [
  { name: 'a10', foo: 'foo', bar: 'bar' },
  { name: 'a2', foo: 'foo', bar: 'bar' },
  { name: 'a1', foo: 'foo', bar: 'bar' },
  { name: 'a12', foo: 'foo', bar: 'bar' },
  { name: 'joker5', foo: 'foo', bar: 'bar' },
  { name: 'joker10', foo: 'foo', bar: 'bar' },
  { name: 'joker2', foo: 'foo', bar: 'bar' },
  { name: 'joker1', foo: 'foo', bar: 'bar' },
  { name: 'joker13', foo: 'foo', bar: 'bar' },
  { name: 'joker9', foo: 'foo', bar: 'bar' },
];

// 오름차순
const getValueOfKeyAsc = (arr, key) => {
  return arr.sort(function (a, b) {
    const valueOfKeyA = a[key].toUpperCase();
    const valueOfKeyB = b[key].toUpperCase();
    return valueOfKeyA.localeCompare(valueOfKeyB, undefined, {
      numeric: true,
      sensitivity: 'base',
    });
  });
};
//내림차순
const getValueOfKeyDesc = (arr, key) => {
  return arr.sort(function (a, b) {
    const valueOfKeyA = a[key].toUpperCase();
    const valueOfKeyB = b[key].toUpperCase();
    return valueOfKeyB.localeCompare(valueOfKeyA, undefined, {
      numeric: true,
      sensitivity: 'base',
    });
  });
};

getValueOfKeyAsc(valueOfKeyArr, 'name');
/*
[
  { name: 'a1', foo: 'foo', bar: 'bar' },
  { name: 'a2', foo: 'foo', bar: 'bar' },
  { name: 'a10', foo: 'foo', bar: 'bar' },
  { name: 'a12', foo: 'foo', bar: 'bar' },
  { name: 'joker1', foo: 'foo', bar: 'bar' },
  { name: 'joker2', foo: 'foo', bar: 'bar' },
  { name: 'joker5', foo: 'foo', bar: 'bar' },
  { name: 'joker9', foo: 'foo', bar: 'bar' },
  { name: 'joker10', foo: 'foo', bar: 'bar' },
  { name: 'joker13', foo: 'foo', bar: 'bar' }
]
*/

getValueOfKeyDesc(valueOfKeyArr, 'name');
/*
[
  { name: 'joker13', foo: 'foo', bar: 'bar' },
  { name: 'joker10', foo: 'foo', bar: 'bar' },
  { name: 'joker9', foo: 'foo', bar: 'bar' },
  { name: 'joker5', foo: 'foo', bar: 'bar' },
  { name: 'joker2', foo: 'foo', bar: 'bar' },
  { name: 'joker1', foo: 'foo', bar: 'bar' },
  { name: 'a12', foo: 'foo', bar: 'bar' },
  { name: 'a10', foo: 'foo', bar: 'bar' },
  { name: 'a2', foo: 'foo', bar: 'bar' },
  { name: 'a1', foo: 'foo', bar: 'bar' }
]
*/

name을 기준으로 정렬된 것을 확인 할수 있다. Good~😎

Reference

profile
왜?를 생각하며 개발하기, 다양한 프로젝트를 경험하는 것 또한 중요하지만 내가 사용하는 기술이 어떤 배경과 이유에서 만들어진 건지, 코드를 작성할 때에도 이게 최선의 방법인지를 끊임없이 질문하고 고민하자. 이 과정은 앞으로 개발자로 커리어를 쌓아 나갈 때 중요한 발판이 될 것이다.

0개의 댓글