배열의 메서드들
이번에는 많이 사용하는 배열의 메서드들에 대해서 한 번 알아보도록 하겠습니다.
배열의 메서드들
Array.from
Array.from 은 유사 배열 객체를 변환해서 배열을 생성합니다. 인수로는 iterable 과 유사 배열을 줄 수 있는데, 이를 배열을 만들어 줍니다.
Array.from({ length: 3 }, (_, i) => i); // -> [0, 1, 2]
Array.prototype.indexOf
원본 배열에서 인수로 전달된 요소를 검색해서 인덱스를 반환해줍니다. 중복되는 요소가 있다면 첫 번째로 검색된 요소의 인덱스를 반환해줍니다. 만약 존재하지 않으면 -1을 반환해줍니다. 대부분 요소의 존재 여부를 확인하기 위해서 사용합니다.
const arr = [1, 2, 2, 3];
// 배열 arr에서 요소 2를 검색하여 첫 번째로 검색된 요소의 인덱스를 반환한다.
arr.indexOf(2); // -> 1
// 배열 arr에 요소 4가 없으므로 -1을 반환한다.
arr.indexOf(4); // -> -1
// 두 번째 인수는 검색을 시작할 인덱스다. 두 번째 인수를 생략하면 처음부터 검색한다.
arr.indexOf(2, 2); // -> 2
ES7 에서는 Array.prototype.includes 메서드를 사용하면 가독성이 좋습니다.
const foods = ['apple', 'banana'];
// foods 배열에 'orange' 요소가 존재하는지 확인한다.
if (!foods.includes('orange')) {
// foods 배열에 'orange' 요소가 존재하지 않으면 'orange' 요소를 추가한다.
foods.push('orange');
}
console.log(foods); // ["apple", "banana", "orange"]
Array.prototype.push
push 메서드는 인수로 전달 받은 모든 값을 원본 배열의 마지막 요소에 추가합니다. 이후 변경된 length 프로퍼티 값은 반환해줍니다. push 메서드는 원본 배열을 직접 변경하는 mutator 입니다.
const arr = [1, 2];
// 인수로 전달받은 모든 값을 원본 배열 arr의 마지막 요소로 추가하고 변경된 length 값을 반환한다.
let result = arr.push(3, 4);
console.log(result); // 4
// push 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [1, 2, 3, 4]
ES6 의 스프레드 문법을 사용하면 함수 호출 없이도 표현식으로 마지막에 요소 추가가 가능합니다. 또한 부수효괴도 존재하지 않기 때문에 스프레드 문법을 사용하는 것이 좋습니다.
const arr = [1, 2];
// ES6 스프레드 문법
const newArr = [...arr, 3];
console.log(newArr); // [1, 2, 3]
Array.prototype.pop
원본 배열에서 맨 뒤의 요소를 제거하고 반환합니다. 빈 배열이라면 undefined 를 반환하고 부수효과가 존재해 원본 배열을 직접 변경합니다.
const arr = [1, 2]; // 원본 배열에서 마지막 요소를 제거하고 제거한 요소를 반환한다. let result = arr.pop(); console.log(result); // 2 // pop 메서드는 원본 배열을 직접 변경한다. console.log(arr); // [1]
Array.of
Array.of 는 ES6 에서 도입됬습니다. Array.of 는 전달된 인수를 요소로 가지는 배열을 생서합니다. Array 생성자 함수와 다르게 전달된 인수가 1개이고, 숫자이더라도 인수를 요소로 가지는 배열을 생성해줍니다.
// 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성한다.
Array.of(1); // -> [1]
Array.of(1, 2, 3); // -> [1, 2, 3]
Array.of('string'); // -> ['string']
Array.from
마찬가지로 ES6 에서 도입되었으며 유사 배열 객체나 이터러블 객체를 인수로 전달 받아서 배열로 변환해줍니다.
// 유사 배열 객체를 변환하여 배열을 생성한다.
Array.from({ length: 2, 0: 'a', 1: 'b' }); // -> ['a', 'b']
// 이터러블을 변환하여 배열을 생성한다. 문자열은 이터러블이다.
Array.from('Hello'); // -> ['H', 'e', 'l', 'l', 'o']
Array.from 은 두 번째 인수로 전달한 콜백 함수로 값을 만들어 채울 수 있습니다. 두 번째 인수로 전달한 콜백 함수에 첫 번째 인수에 의해서 생성된 배열의 요소값과 ㅇ니덱스를 순차적으로 전달하고 호출하며 콜백 함수의 반환값으로 구성된 배열을 반환해줍니다.
// Array.from에 length만 존재하는 유사 배열 객체를 전달하면 undefined를 요소로 채운다.
Array.from({ length: 3 }); // -> [undefined, undefined, undefined]
// Array.from은 두 번째 인수로 전달한 콜백 함수의 반환값으로 구성된 배열을 반환한다.
Array.from({ length: 3 }, (_, i) => i); // -> [0, 1, 2]
Array.prototype.slice
slice 메서드는 인수로 전달한 범위의 요소들을 복사하고 배열로 반환해줍니다. 원본 배열이 변경되지 않고 두 개의 매개변수를 가집니다.
1. start : 복사를 시작할 인덱스입니다. 음수로 지정하는 경우에는 배열의 맨 뒤에서부터 시작합니다.
2. end : 복사를 종료할 인덱스입니다. 인덱스에 해당하는 요소는 복사되지 않습니다. (부등호 '<' 개념) end 는 생략이 가능한데, 생략 시에는 length 의 프로퍼티 값이 됩니다.
const arr = [1, 2, 3];
// arr[0]부터 arr[1] 이전(arr[1] 미포함)까지 복사하여 반환한다.
arr.slice(0, 1); // -> [1]
// arr[1]부터 arr[2] 이전(arr[2] 미포함)까지 복사하여 반환한다.
arr.slice(1, 2); // -> [2]
// 원본은 변경되지 않는다.
console.log(arr); // [1, 2, 3]
인수를 생략하면 첫 번째 인수부터 시작해서 모든 요소를 복사해 배열로 반환합니다.
const arr = [1, 2, 3];
// arr[1]부터 이후의 모든 요소를 복사하여 반환한다.
arr.slice(1); // -> [2, 3]
// 첫 번째 인수가 음수라면 끝에서부터 시작한다.
const arr = [1, 2, 3];
// 배열의 끝에서부터 요소를 한 개 복사하여 반환한다.
arr.slice(-1); // -> [3]
// 배열의 끝에서부터 요소를 두 개 복사하여 반환한다.
arr.slice(-2); // -> [2, 3]
// 메서드의 인수를 모두 생략하면 원본 배열의 복사본을 생성해서 반환한다.
const arr = [1, 2, 3];
const copy = arr.slice();
console.log(copy); // [1, 2, 3]
console.log(copy === arr); // false
Array.prototype.fill
ES6 에서 도입됬으며 fill 메서드를 통해서 인수로 전달 받은 값을 배열에 요소로 채워줍니다. 원본 배열이 변경되므로 주의해야 합니다. 만약 두 번째 인수를 전달하면 요소 채우기를 시작할 인덱스의 전달이 가능합니다. 세 번째 인수는 요소 채우기를 끝낼 인덱스의 전달이 가능합니다.
const arr = [1, 2, 3];
// 인수로 전달 받은 값 0을 배열의 처음부터 끝까지 요소로 채운다.
arr.fill(0);
// fill 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [0, 0, 0]
const arr = [1, 2, 3];
// 인수로 전달받은 값 0을 배열의 인덱스 1부터 끝까지 요소로 채운다.
arr.fill(0, 1);
// fill 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [1, 0, 0]
const arr = [1, 2, 3, 4, 5];
// 인수로 전달받은 값 0을 배열의 인덱스 1부터 3 이전(인덱스 3 미포함)까지 요소로 채운다.
arr.fill(0, 1, 3);
// fill 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [1, 0, 0, 4, 5]
Array.from 은 두 번째 인수로 전달한 콜백 함수로 값을 만들어 채울 수 있습니다. 두 번째 인수로 전달한 콜백 함수에 첫 번째 인수에 의해서 생성된 배열의 요소값과 ㅇ니덱스를 순차적으로 전달하고 호출하며 콜백 함수의 반환값으로 구성된 배열을 반환해줍니다.
// Array.from에 length만 존재하는 유사 배열 객체를 전달하면 undefined를 요소로 채운다.
Array.from({ length: 3 }); // -> [undefined, undefined, undefined]
// Array.from은 두 번째 인수로 전달한 콜백 함수의 반환값으로 구성된 배열을 반환한다.
Array.from({ length: 3 }, (_, i) => i); // -> [0, 1, 2]
Array.prototype.sort
배열의 요소 정렬이 가능합니다. 원본 배열을 직접 변경합니다. 기본적으로 오름차순으로 요소를 정렬하는데, 한글 문자열도 정렬이 됩니다. 하지만 숫자 요소로 이루어진 배열을 정렬할 때에는 주의가 필요합니다.
const points = [40, 100, 1, 5, 2, 25, 10];
points.sort();
// 숫자 요소들로 이루어진 배열은 의도한 대로 정렬되지 않는다.
console.log(points); // [1, 10, 100, 2, 25, 40, 5]
Ar이는 숫자 요소라 할지라도 일시적으로 문자열로 변환한 후에 순서를 맞춰서 정렬하기 때문입니다. 따라서 숫자 요소를 정려하려면 정렬 순서를 정의하는 비교 함수를 인수로 전달해야 합니다. 비교 함수는 양수, 음수, 0 을 반환해야 합니다. 0보다 작으면 첫 번째 인수를 우선해 정렬하고, 0이면 정렬하지 않으며, 0보다 크면 두번째 인수를 우선해서 정렬합니다.
const points = [40, 100, 1, 5, 2, 25, 10];
// 숫자 배열의 오름차순 정렬
points.sort((a, b) => a - b);
console.log(points); // [1, 2, 5, 10, 25, 40, 100]
// 숫자 배열에서 최소/최대값 취득
console.log(points[0], points[points.length - 1]); // 1 100
// 숫자 배열의 내림차순 정렬
points.sort((a, b) => b - a);
console.log(points); // [100, 40, 25, 10, 5, 2, 1]
// 숫자 배열에서 최대값 취득
console.log(points[0]); // 100
Array.prototype.map
map 메서드는 자신을 호출한 배열의 모든 요소를 순회하며 인수로 전달받은 콜백 함수를 반복해서 호출합니다. 이후 콜백 함수의 반환값들로 구성된 새로운 배열을 반환합니다. 이때 원본 배열의 변경이 일어나지 않습니다.
forEach 메서드와 map 메서드는 자신을 호출한 배열의 모든 요소를 순회하고 인수로 전달받은 콜백 함수를 반복해서 호출한다는 것입니다. 하지만 forEach 는 언제나 undefined 를 반환합니다. map 메서드는 반환값들로 새로운 배열을 만들어 반환해줍니다. forEach 의 경우는 단순하게 반복문을 대체하는 고차 함수이며 map 메서드는 다른 값으로 매핑한 새로운 배열을 생성하는 고차 함수입니다.
// map 메서드는 콜백 함수를 호출하면서 3개(요소값, 인덱스, this)의 인수를 전달한다.
[1, 2, 3].map((item, index, arr) => {
console.log(`요소값: ${item}, 인덱스: ${index}, this: ${JSON.stringify(arr)}`);
return item;
});
/*
요소값: 1, 인덱스: 0, this: [1,2,3]
요소값: 2, 인덱스: 1, this: [1,2,3]
요소값: 3, 인덱스: 2, this: [1,2,3]
*/
이 경우에 map 메서드가 반환한 새로운 배열의 length 는 map 메서드를 호출한 배열의 length 프로퍼티의 값보다 같습니다.
Array.prototype.filter
filter 메서드는 map, forEach 와 동일하게 동작하지만 콜백 함수로 truthy, falsy 의 결과를 가지는 함수를 인수로 받습니다. 이후에 콜백 함수의 반환값이 true 인 요소로만 구성된 새로운 배열을 만들어서 반환해줍니다. 원본 배열은 변경되지 않습니다.
const numbers = [1, 2, 3, 4, 5];
// filter 메서드는 numbers 배열의 모든 요소를 순회하면서 콜백 함수를 반복 호출한다.
// 그리고 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환한다.
// 다음의 경우 numbers 배열에서 홀수인 요소만을 필터링한다(1은 true로 평가된다).
const odds = numbers.filter(item => item % 2);
console.log(odds); // [1, 3, 5]
Array.prototype.reduce
reduce 메서드는 콜백 함수의 반환값을 다음 순회의 콜백 함수의 첫 번째 인수로 전달합니다. 그리고 이를 하나의 결과값으로 만들어서 반환합니다. 이때 원본 배열은 변경되지 않습니다.
reduce 메서드는 첫 번째 인수로 콜백 함수, 두 번째 인수로 초기값을 전달받습니다. reduce 메서드의 콜백 함수에는 4개의 인수를 전달 받습니다. 계속해서 더해질 초기값과 이전 반환값, 요소값과 인덱스, 호출한 배열 자체인 this 를 전달받습니다.
reduce 메서드는 초기값과 배열의 첫 번째 요소갑을 콜백 함수의 인수로 전달해 호출합니다. 다음 순회부터 콜백 함수의 반환값과 두 번째 요소값을 콜백 함수의 인수로 전달하고 호출하는 과정을 반복해 하나의 결과값을 반환하게 됩니다.
// [1, 2, 3, 4]의 모든 요소의 누적을 구한다.
const sum = [1, 2, 3, 4].reduce((accumulator, currentValue, index, array) => accumulator + currentValue, 0);
console.log(sum); // 10
// 가변 인자 예시
// const sum = ( ...args) => args.reduce((pre, cur, i, arr) => pre + cur, 0);
마무리
이번에는 자주 사용하는 배열의 메서드들에 대해서 알아봤습니다. 자바스크립트에서는 배열을 많이 사용하기 때문에 메서드들에 대해서 공부해보는 것이 중요합니다. 특히 map, filter 의 경우 많이 사용되기 때문에 중점적으로 알아둬야 할 필요가 있습니다.
보다 더 자세한 내용은 아래 링크에서 확인 가능하고, 저 또한 내용들을 공부하며 정리하기 위한 목적으로 글을 남기는 것을 알려드립니다. 읽어주셔서 감사합니다!
'자바스크립트 > 자바스크립트 정리' 카테고리의 다른 글
[자바스크립트] 이터러블 (0) | 2021.06.06 |
---|---|
[자바스크립트] Symbol (0) | 2021.06.06 |
[자바스크립트] 배열 (0) | 2021.06.02 |
[자바스크립트] 정렬 구현해보기 (0) | 2021.06.01 |
[자바스크립트] ES6 의 함수 (0) | 2021.05.30 |