트랙
/
JavaScript
JavaScript
/
연습 문제
/
Elyse의 변환 마법
Elyse의 변환 마법

Elyse의 변환 마법

학습 연습 문제

소개

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']

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

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

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

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 } ]

지침

마술사 지망생 Elyse는 훈련을 계속해요. Elyse는 카드 덱을 받아서 그 덱을 변형시키려고 해요. 특정 카드가 나타나게 하거나, 사라지게 하거나, 값이 바뀌게 하거나, 순서를 완전히 바꾸는 마법을 부려요. 일을 좀 더 쉽게 하려고 Elyse는 보통 1부터 10까지의 숫자가 적힌 카드로만 시작해요. 물론 어떤 마법은 더 큰 숫자의 카드를 만들어 내기도 해요.

1. 모든 카드를 두 배로 만들기

Elyse는 덱에 있는 모든 카드의 숫자를 두 배로 만들고 싶어 해요. 그러면 1부터 10까지보다 큰 카드가 만들어질 수도 있어요.

const deck = [1, 2, 3, 4, 10];
seeingDouble(deck);
// => [2, 4, 6, 8, 20]

2. 덱에 있는 모든 3의 복사본 여러 개 만들기

Elyse는 덱에 있는 모든 3을 세 개로 늘리고 싶어 해요. 3이 하나 들어 있는 덱이라면, 마법을 부린 뒤에는 원래의 3 대신 3이 세 개 있게 돼요.

const deck = [1, 3, 9, 3, 7];
threeOfEachThree(deck);
// => [1, 3, 3, 3, 9, 3, 3, 3, 7]

3. 덱의 정확한 가운데에서 카드 두 장 찾기

Elyse는 카드 열 장짜리 덱을 가져다가 가운데 두 장을 제외한 모든 카드를 사라지게 할 거예요.

const deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
middleTwo(deck);
// => [5, 6]

4. 양쪽 끝 카드 두 장이 덱 가운데에 다시 나타나기

Elyse는 덱의 맨 위 카드와 맨 아래 카드를 뒤집힌 순서로 가운데로 옮기고 싶어 해요.

덱에 짝수 개의 카드가 있다고 가정해도 돼요.

const deck = [1, 2, 3, 5, 6, 10];
sandwichTrick(deck);
// => [2, 3, 10, 1, 5, 6]

5. 2가 아닌 모든 카드 사라지기

오늘 Elyse가 가장 좋아하는 숫자는 2예요. 이 마법에서는 2가 아닌 카드는 모두 덱에서 사라져요.

const deck = [1, 2, 3, 4, 10, 2];
twoIsSpecial(deck);
// => [2, 2]

6. 섞인 덱을 완벽하게 정렬된 덱으로 바꾸기

Elyse는 카드를 완벽하게 다시 정렬하는 솜씨를 보여주고 싶어 해요. 아무리 잘 섞여 있어도 말이죠.

const deck = [10, 1, 5, 3, 2, 8, 7];
perfectlyOrdered(deck);
// => [1, 2, 3, 5, 7, 8, 10]

7. 덱 순서 바꾸기

Elyse는 덱에 있는 카드의 순서를 바꾸고 싶어 해요. 마법을 부린 뒤에는 지금 맨 위에 있는 카드가 덱의 맨 아래로 가야 해요. 두 번째 카드는 끝에서 두 번째로 가고, 그다음 카드도 같은 식으로 가야 해요.

const deck = [10, 1, 5, 3, 2];
reorder(deck);
// => [2, 3, 5, 1, 10]
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
JavaScript Exercism

Elyse의 변환 마법 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 JavaScript 트랙을 개념 37개연습 문제 159개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.