배열

배열 변환 에서 JavaScript

20개의 연습 문제

배열 변환 소개

JavaScript에서 Array 클래스에는 배열을 변환하는 강력한 내장 메서드가 많아요. 이런 메서드를 사용하면 단순한 for문이나 더 직접적인 조작으로 배열을 다른 배열로 바꾸는 것보다 훨씬 쉬워요.

일부 메서드는 순수 함수예요. 즉, 원본 배열을 수정하지 않고 새로운 배열을 반환해요. 하지만 다른 메서드들은 자신이 호출된 배열을 직접 조작하고, 수정된 배열을 반환하지 않아요.

배열을 변환할 때 가장 많이 쓰이는 메서드 몇 가지를 아래에서 소개해요. 사용할 수 있는 전체 메서드 목록은 MDN 문서에서 볼 수 있어요.

map (순수 함수)

인자로 전달된 함수에 따라 각 원소를 변환해서 새로운 배열을 만들어요. 이런 콜백 함수는 보통 화살표 함수로 작성해요.

let arr = [1, 2, 3, 4];

const newArr = arr.map((value) => value - 1);
console.log(newArr);
// => [0, 1, 2, 3]
console.log(arr);
// => [1, 2, 3, 4]

결과로 나오는 배열의 길이는 언제나 원본과 같다는 점을 기억해 둘 만해요.

filter (순수 함수)

필터링 함수, 즉 원소를 남겨야 하면 true를, 제거해야 하면 false를 반환하는 함수를 받아서 현재 배열을 걸러낸 새로운 배열을 만들어요.

let arr = [1, 2, 3, 4];

arr.filter((value) => value % 2 === 0);
// => [2, 4]

reduce (순수 함수)

_누산기_와 배열의 현재 원소를 매개변수로 받는 함수를 사용해서 배열을 하나의 값으로 줄여요. 이 함수는 현재 원소를 누산기에 어떻게 합쳐야 하는지 알려 주고, 다음 반복에서 사용할 누산기를 반환해요.

let arr = [1, 2, 3, 4];

// Get the sum of elements
arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
// => 10

// Classify the numbers by whether they are odd or not
arr.reduce(
  (accumulator, currentValue) => {
    if (currentValue % 2 === 0) {
      accumulator.even.push(currentValue);
    } else {
      accumulator.odd.push(currentValue);
    }

    return accumulator;
  },
  { even: [], odd: [] },
);
// => { even: [2, 4], odd: [1, 3] }

reverse

배열의 원소 순서를 뒤집어요.

const arr = [1, 2, 3, 4];

arr.reverse();
// => [4, 3, 2, 1]

이 메서드는 자신이 호출된 배열을 수정해요.

slice (순수 함수)

시작 인덱스와 끝 인덱스가 주어지면, 자신이 호출된 배열에서 부분 배열을 만들어요.

끝 인덱스에 있는 원소는 포함되지 않아요. 또한 모든 매개변수는 선택 사항이에요. 시작 인덱스의 기본값은 0이고, 끝 인덱스의 기본값은 배열의 길이예요.

const arr = [1, 2, 3, 4];

arr.slice(1, 2); // [2]
arr.slice(1); // [2, 3, 4]
// You can also use negative numbers, that represent the indexes
// starting from the end of the array
arr.slice(-2); // [3, 4]

splice

배열의 원소를 제거하거나 교체하고, 또는 새로운 원소를 추가해요. 다음 매개변수를 받아요.

  • 배열 수정을 시작할 원소의 인덱스
  • 삭제할 원소의 개수
  • 배열에 삽입할 원소 (선택 사항)

splice는 제거된 원소를 반환해요.

const arr = ['1', '2', '5', '6'];

// Insert an element at index 2
arr.splice(2, 0, '3');
console.log(arr);
// => ['1', '2', '3', '5', '6']

// Remove 2 elements, starting at index 3 and insert 2 elements
const removed = arr.splice(3, 2, '4', '5');
console.log(removed);
// => ['5', '6']
console.log(arr);
// => ['1', '2', '3', '4', '5']

// Remove 1 element at index 1
arr.splice(1, 1);
console.log(arr);
// => ['1', '3', '4', '5']

sort

기본적으로 sort는 배열의 원소를 먼저 문자열로 변환한 다음 문자열 비교를 적용해서 정렬해요(비교 개념 참고). 정렬은 제자리에서 일어나기 때문에 원본 배열이 수정돼요. sort는 이렇게 수정된 배열도 반환하는데, 여기에 다른 메서드를 연이어 호출하고 싶을 때 편리해요.

const arr = ['c', 'a', 'z', 'b'];
const result = arr.sort();
console.log(result);
// => ['a', 'b', 'c', 'z']
console.log(arr);
// => ['a', 'b', 'c', 'z']
Caution

이 기본 동작은 숫자를 정렬하려고 할 때 잘못된 결과를 낳아요.

const arr = [3, 1, 2, 10];
arr.sort();
// => [1, 10, 2, 3]
// Because the string '10' comes before '2' in dictionary order.

정렬 동작을 원하는 대로 바꾸려면 비교 함수를 인자로 전달할 수 있어요. 비교 함수는 배열의 두 원소를 인자로 받아 호출돼요. 그리고 다음 중 하나를 반환해야 해요.

  • 첫 번째 인자가 두 번째 인자보다 앞에 정렬되어야 하면 음수
  • 첫 번째 인자가 두 번째 인자보다 뒤에 정렬되어야 하면 양수
  • 원소의 순서가 그대로 유지되어야 하면 0

이렇게 하면 올바른 비교 함수를 전달해서 숫자 정렬 문제를 해결할 수 있어요.

const arr = [3, 1, 2, 10];
arr.sort((a, b) => a - b);
// => [1, 2, 3, 10]
// "a - b" is negative when b is greater than a, positive when
// a is greater than b and 0 when they are equal.

다음은 사용자 정의 비교 함수를 사용해서 객체 배열을 정렬하는 예시예요.

const arr = [
  { name: 'Lydia', age: 7 },
  { name: 'Anne', age: 34 },
  { name: 'Holger', age: 59 },
];

arr.sort((item1, item2) => {
  if (item1.name < item2.name) {
    return -1;
  }
  if (item1.name > item2.name) {
    return 1;
  }
  return 0;
});
// => [ { name: 'Anne', age: 34 }, { name: 'Holger', age: 59 },
// { name: 'Lydia', age: 7 } ]

2019년부터 언어 명세에서는 정렬이 안정적이어야 한다고 규정하지만, 성능(시간과 공간 복잡도)에 대해서는 보장하지 않아요.

GitHub에서 편집 링크가 새 창이나 탭에서 열려요

배열 변환 배우기