[JAVASCRIPT.INFO] 5.5 배열과 메서드
5.5 배열과 메서드
요소 추가, 제거 매서드
splice
arr.splice(index [, deleteCount, elem1, ..., elemN])
첫 번째 매개변수는 조작을 가할 첫 번째 요소를 가리키는 index
, 두 번째 매개변수는 deleteCount
로, 제거하고자 하는 요소의 개수를 나타내고, elem1, ..., elemN
은 배열에 추가할 요소를 나타낸다.
let arr = ["I", "study", "JavaScript"];
arr.splice(1,1); // index 1부터 요소 1개 제거
alert(arr); ["I", "JavaScript"]
let arr = ["I", "study", "JavaScript", "right", "now"];
// 처음 세 개의 요소를 지우고, 다른 요소로 대체
arr.splice(0, 3, "Let's", "dance");
alert(arr); // ["Let's", "dance", "right", "now"];
splice
는 삭제된 요소로 구성된 배열을 반환함
let arr = ["I", "study", "JavaScript", "right", "now"];
let removed = arr.splice(0,2);
alert(removed); // ["I", "study"];
let arr = ["I", "study", "JavaScript"];
// index 2부터 0개의 요소를 삭제하고 요소를 추가함
arr.splice(2, 0, "complex", "language");
alert(arr); // ["I", "study", "complex", "language", "JavaScript"];
let arr = [1,2,5];
// index -1부터(끝에서부터 첫 번째 요소)
// 0개의 요소를 삭제하고
// 3, 4를 추가
arr.splice(-1, 0, 3, 4);
alert(arr); // [1, 2, 3, 4, 5];
concat
concat
의 인수엔 배열이나 값이 올 수 있는데, 인수 개수엔 제한이 없다. 메서드를 호출하면 arr
에 속한 모든 요소와 arg1
, arg2
등에 속한 모든 요소를 한데 모은 새로운 배열이 반환된다. 인수 argN
이 배열인 경우 배열의 모든 요소가 복사된다.
let arr = [1,2];
alert(arr.concat([3,4])); // 1,2,3,4
alert(arr.concat([3,4], 5,6)); // 1,2,3,4,5,6
객체가 인자로 넘어오면 객체는 분해되지 않고 통으로 복사되어 더해진다.
let arr = [1,2];
let arrayLike = {
0: "something",
length: 1
}
alert(arr.concat(arrayLike)); //1,2,[object, Object]
인자로 받은 유사 배열 객체에 특수한 프로퍼티 Symbol.isConcatSpreadable
이 있으면 concat
은 이 객체를 배열처럼 취급한다.
let arr = [1,2];
let arrayLike = {
0: "something",
1: "else",
[Symbol.isConcatSpreadable]: true,
length: 2
};
alert(arr.concat(arrayLike)); // 1,2,something,else
배열 탐색하기
find와 findIndex
객체로 이루어진 배열이 있을 때 특정 조건에 부합하는 객체를 배열 내에서 찾고자 한다면 find 메서드를 사용하면 된다.
item
- 함수를 호출할 요소index
- 요소의 인덱스array
- 배열 자기 자신
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"},
];
let user = users.find(item => item.id == 1);
alert(user.name); // John
filter
find
메서드는 함수의 반환 값을 true
로 만드는 단 하나의 요소를 찾는 반면 조건을 충족하는 요소가 여러 개일 때는 filter
를 사용하면 된다.
배열을 변형하는 메서드
reduce와 reduceRight
reduce
와 reduceRight
는 배열을 기반으로 값 하나를 도출할 때 사용된다.
let value = arr.reduce(function(accumulator, item, index, array) {
}, [initial])
accumulator
- 이전 함수의 호출의 결과.initial
은 함수 최초 호출 시 사용되는 초깃값을 나타냄item
- 현재 배열 요소index
- 요소의 위치array
- 배열
이전 함수 호출 결과는 다음 함수를 호출 할 때 첫 번째 인수(previousValue
)로 사용된다
첫 번째 인수는 앞서 호출했던 함수들의 결과가 누적되어 저장되는 'accumulator'라고 생각하면 된다. 마지막 함수까지 호출되면 이 값은 reduce
의 반환 값이 된다.
let arr = [1,2,3,4,5];
let result = arr.reduce((sum, current) => sum + current, 0);
// let result = arr.reduce((sum, current) => sum+current); // 초깃값 생략 가능
alert(result); // 15
- 함수 최초 호출 시,
reduce
의 마지막 인수인0(초깃값)
이sum
에 할당된다.current
엔 배열의 첫 번째 요소인1
이 할당된다. 따라서 함수의 결과는1
이 된다. - 두 번째 호출 시,
sum = 1
이고 여기에 배열의 두 번째 요소가 더해지므로 결과는3
이 된다. - 세 번째 호출 시,
sum = 3
이고 여기에 배열의 세 번째 요소가 더해진다. 반복
초깃값이 생략될 경우 배열이 비어있는 상태면 reduce
호출 시 에러가 발생하기 때문에 항상 초깃값을 명시해 줄 것을 권장한다.
reduceRight
는 reduce
와 동일한 기능을 하지만 배열의 오른쪽부터 연산을 수행한다.
Array.isArray로 배열 여부 알아내기
자바스크립트에서 배열은 독립된 자료형으로 취급되지 않고 객체형에 속하기 때문에 typeof
로는 일반 객체와 배열을 구분할 수 없다. 따라서 Array.isArray
메서드를 이용하여 배열인지 구분가능하다.
배열 메서드와 'thisArg'
함수를 호출하는 대부분의 배열 메서드는 thisArg
라는 매개변수를 옵션으로 받을 수 있다.
thisArg
는 다음과 같이 활용할 수 있다.
arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
// ...
// thisArg는 선택적으로 사용할 수 있는 마지막 인수이다.
thisArg
는 func
의 this
가 된다.
let army = {
minAge: 18,
maxAge: 27,
canJoin(user) {
return user.age >= this.minAge && user.age < this.maxAge
}
};
let users = [
{age: 16},
{age: 20},
{age: 23},
{age: 30},
];
// army.canJoin 호출 시 참을 변환해주는 user를 찾음
let soldiers = users.filter(army.canJoin, army);
alert(soldiers.length); // 2
alert(soldiers[0].age); // 20
alert(soldiers[1].age); // 23
army
의 메서드를 filter
의 인자로 넘겨주고 있는데, 이 때 thisArg
는 canJoin
의 컨텍스트 정보를 넘겨준다.
thisArg
에 army
를 지정하지 않고 단순히 users.filter(army.canJoin)
를 사용했다면 army.canJoin
은 단독 함수처럼 취급되고, 함수 본문 내 this
는 undefined
가 되어 에러가 발생했을 것이다.
users.filter(user => army.canJoin(user))
를 사용하면 users.filter(army.canJoin, army)
를 대체할 수 있긴한데 thisArg
를 사용하는 방식이 좀 더 이해하기 쉬우므로 더 자주 사용된다.