JavaScript에는 개수가 정해지지 않은 여러 원소를 다루기 쉽게 해 주는 ... 연산자가 내장되어 있어요. 문맥에 따라 이 연산자를 rest 연산자 또는 _spread 연산자_라고 불러요.
...이 할당의 왼쪽에 나타나면, 이 세 개의 점을 rest 연산자라고 해요. 세 개의 점과 변수 이름을 함께 묶은 것을 rest 원소라고 하는데, rest 원소는 0개 이상의 값을 모아서 하나의 배열에 저장해요.
const [a, b, ...everythingElse] = [0, 1, 1, 2, 3, 5, 8];
a;
// => 0
b;
// => 1
everythingElse;
// => [1, 2, 3, 5, 8]
다른 언어와 달리 JavaScript에서는 rest 원소 뒤에 쉼표를 붙일 수 없다는 점에 주의하세요. rest 원소는 구조 분해 할당에서 반드시 마지막 원소여야 해요. 아래 예제는 SyntaxError를 발생시켜요.
const [...items, last] = [2, 4, 8, 16]
배열과 마찬가지로, rest 연산자를 사용하면 하나 이상의 객체 프로퍼티를 모아서 하나의 객체에 저장할 수도 있어요.
const { street, ...address } = {
street: 'Platz der Republik 1',
postalCode: '11011',
city: 'Berlin',
};
street;
// => 'Platz der Republik 1'
address;
// => {postalCode: '11011', city: 'Berlin'}
...이 함수 정의에서 마지막 인자 옆에 나타나면, 그 매개변수를 _rest 매개변수_라고 해요. rest 매개변수를 사용하면 함수가 개수가 정해지지 않은 여러 인자를 배열로 받을 수 있어요.
function concat(...strings) {
return strings.join(' ');
}
concat('one');
// => 'one'
concat('one', 'two', 'three');
// => 'one two three'
...이 할당의 오른쪽에 나타나면, spread 연산자라고 해요. spread 연산자는 배열을 원소들의 목록으로 펼쳐요. rest 원소와 달리, 배열 리터럴 표현식의 어디에나 나타날 수 있고, 두 개 이상 사용할 수도 있어요.
const oneToFive = [1, 2, 3, 4, 5];
const oneToTen = [...oneToFive, 6, 7, 8, 9, 10];
oneToTen;
// => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const woow = ['A', ...oneToFive, 'B', 'C', 'D', 'E', ...oneToFive, 42];
woow;
// => ["A", 1, 2, 3, 4, 5, "B", "C", "D", "E", 1, 2, 3, 4, 5, 42]
배열과 마찬가지로, spread 연산자를 사용하면 한 객체의 프로퍼티를 다른 객체로 복사할 수도 있어요.
let address = {
postalCode: '11011',
city: 'Berlin',
};
address = { ...address, country: 'Germany' };
// => {
// postalCode: '11011',
// city: 'Berlin',
// country: 'Germany',
// }
친구인 Linus는 도시 사이를 오가며 화물 열차를 운전하는 기관사예요. 열차를 다루는 일은 정말 잘하지만, 물류나 컴퓨터를 다루는 일은 그렇지 않아요. 그래서 열차 정보를 정리하고 경로 데이터의 실수를 고치는 일에 여러분의 프로그래밍 도움을 받고 싶어 해요.
연습을 위해 아래 과제를 풀 때는 나머지 연산자나 전개 연산자를 사용해 봐요.
친구는 각 화물칸의 식별자(ID)를 계속 기록해 왔지만, 시스템이 어느 시점에 몇 개의 화물칸을 처리해야 할지는 전혀 알 수 없어요.
이 데이터가 하나의 array로 묶여 있으면 나머지 물류 프로그램이 훨씬 편해질 거예요.
각 화물칸의 ID를 임의의 개수만큼 받는 getListOfWagons 함수를 구현해요.
각 ID는 양의 정수예요.
그러면 함수는 주어진 ID들을 하나의 array로 반환해야 해요.
getListOfWagons(1, 7, 12, 3, 14, 8, 5);
// => [1, 7, 12, 3, 14, 8, 5]
이쯤 되면 데이터와 물류 프로그램에서 데이터가 어떻게 쓰이는지 감이 잡히기 시작할 거예요. ID 시스템은 기관차에 항상 1이라는 ID를 부여하고, 열차의 나머지 화물칸에는 1보다 큰 임의의 ID를 부여해요.
친구는 새 화물칸 두 개를 열차에 연결해 놓고 시스템 갱신을 잊었어요!
이제 열차 array의 처음 두 화물칸을 끝으로 옮겨야 해요. 그러지 않으면 순서가 전부 뒤엉켜요.
Linus는 실수를 고쳐 주면 정말 고마워할 거예요.
각 화물칸의 id로 이루어진 배열을 받는 fixListOfWagons 함수를 구현해요.
이 함수는 처음 두 원소를 array 끝으로 옮겨 기관차가 맨 앞에 오도록 한 array를 return해요.
eachWagonsID = [2, 5, 1, 7, 4, 12, 6, 3, 13];
fixListOfWagons(eachWagonsID);
// => [1, 7, 4, 12, 6, 3, 13, 2, 5]
이런, 화물칸 몇 개가 사라진 것 같아요.
다행히 친구가 빠진 화물칸 ID가 들어 있는 것 같은 또 다른 array를 막 찾았고, 이걸 원래 화물칸 ID array에 추가했으면 해요.
다만 빠진 값들이 지정된 기관차 바로 뒤에 와야 한다는 것만 기억하고 있어요.
이 정보를 바탕으로, 각 화물칸의 ID를 담은 배열 두 개를 인자로 받는 correctListOfWagons 함수를 작성해요.
두 번째 array의 화물칸 ID는 첫 번째 array에서 기관차(ID 1) 바로 뒤에 추가되어야 해요.
eachWagonsID = [1, 5, 20, 7, 4, 8];
missingWagons = [3, 17, 6, 15];
correctListOfWagons(eachWagonsID, missingWagons);
// => [1, 3, 17, 6, 15, 5, 20, 7, 4, 8]
이제 화물칸 데이터가 모두 올바르니, 친구는 시스템의 경로 정보를 갱신해 주길 바라요.
처음 경로 정보는 object로 만들어져 있고, 친구는 제공된 추가 정보로 이걸 갱신해 주길 원해요.
경로마다 필요한 정보가 조금씩 다르기 때문에, 친구는 범용적인 해법을 정말 원해요.
object 두 개를 받는 extendRouteInformation 함수를 구현해요.
첫 번째 object에는 열차 경로가 오가는 도시가 들어 있어요.
두 번째 object에는 열차 속도나 길이 같은 다른 경로 세부 정보가 들어 있어요.
이 함수는 모든 경로 정보를 하나로 합친 objects를 반환해야 해요.
변수 moreRouteInformation에는 서로 다른 속성이 들어 있을 수 있어요.
route = { from: 'Berlin', to: 'Hamburg' };
moreRouteInformation = { length: '100', speed: '50' };
extendRouteInformation(route, moreRouteInformation);
// => {from: "Berlin", to: "Hamburg", length: "100", speed: "50"}
친구는 경로 정보에 도착 시간이 필요 없다는 걸 알아챘어요. 그래서 경로 정보에서 도착 시간을 분리해 주길 바라요.
경로 정보가 담긴 객체를 받는 separateTimeOfArrival 함수를 구현해요.
이 함수는 첫 번째 원소가 도착 시간이고, 두 번째 원소가 도착 시간을 뺀 경로 정보를 담은 객체인 배열을 반환해야 해요.
routeInformation = {
from: 'Berlin',
to: 'Hamburg',
length: '100',
timeOfArrival: '10:10',
};
separateTimeOfArrival(routeInformation);
// => ["10:10", {from: "Berlin", to: "Hamburg", length: "100"}]
Exercism에 가입하고 JavaScript 트랙을 개념 37개연습 문제 159개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.