Modern Javascript 배열과 메서드

[Modern Javascript] 배열과 메서드


본 내용은 모던 자바스크립트 배열과 메서드을 보고 공부, 정리한 내용입니다.

요소 추가, 제거 메서드

push, pop, unshift, shift는 이전에 다루었으므로 생략한다.

splice(index [, deleteCount, arg1, arg2..])

splice 메서드는 잘 사용하면 요소 추가, 삭제, 교체가 모두 가능하다.
arr.splice는 arr에서 index부터 deleteCount 개수를 잘라 반환하는 기능이다.
deleteCount가 주어지지 않으면 index부터 배열 끝까지 잘라 반환한다.

1
2
3
4
5
const a = [1,2,3,4];
const b = a.splice(1);

console.log(b); // [2, 3, 4]
console.log(a); // [1]

deleteCount를 인자로 주면 해당 개수만큼 요소가 삭제된 배열을 얻을 수 있다.

1
2
3
4
const a = [1,2,3,4];
a.splice(1, 2); // 인덱스 1에서부터 2개 요소 삭제

console.log(a); // [1,4]

deleteCount 뒤에 인자를 주면, 삭제 후 해당 요소들을 index 자리에 삽입한다.
deleteCount를 0으로 주고 추가할 인자를 주면, 원하는 위치에 원하는 요소를 추가하는 효과를 낼 수 있다.

1
2
3
4
5
6
let arr = ["I", "study", "JavaScript", "right", "now"];

// 처음 두 개의 요소를 삭제함
arr.splice(0, 2, "Play", "With");

console.log( arr ); // [ 'Play', 'With', 'JavaScript', 'right', 'now' ]
  • 참고
    배열 관련 메서드에는 음수 인덱스를 사용할 수 있다. -n 은 뒤에서부터 n번째 인덱스를 의미한다.

slice([start], [end])

start부터 end 미만까지의 요소들을 복사하여 반환한다.

1
2
3
let arr = ["t", "e", "s", "t"];
alert( arr.slice(1, 3) ); // e,s (인덱스가 1인 요소부터 인덱스가 3인 요소까지를 복사(인덱스가 3인 요소는 제외))
alert( arr.slice(-2) ); // s,t (인덱스가 -2인 요소부터 제일 끝 요소까지를 복사)

concat(arg1, arg2…)

배열과 인자들을 합친 배열을 반환한다.
인자가 배열일 경우, 인자 배열 내 요소들이 복사되어 만들어진다.
그렇지 않으면 해당 요소 자체가 복사된다.

1
2
3
4
5
6
7
8
9
10
let arr = [1, 2];

// arr의 요소 모두와 [3,4]의 요소 모두를 한데 모은 새로운 배열이 만들어집니다.
alert( arr.concat([3, 4]) ); // 1,2,3,4

// arr의 요소 모두와 [3,4]의 요소 모두, [5,6]의 요소 모두를 모은 새로운 배열이 만들어집니다.
alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6

// arr의 요소 모두와 [3,4]의 요소 모두, 5와 6을 한데 모은 새로운 배열이 만들어집니다.
alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6

만약 concat의 인자로 주어진 값이 객체이면, 객체 자체가 복사된다.
객체에 Symbol.isConcatSpreadable 키가 존재한다면 이 객체는 배열처럼 취급된다. 따라서 이 객체가 concat의 인자로 주어지면 객체의 각 속성이 복사된다.

1
2
3
4
5
6
7
8
9
10
let arr = [1, 2];

let arrayLike = {
  0: "something",
  1: "else",
  [Symbol.isConcatSpreadable]: true,
  length: 2
};

alert( arr.concat(arrayLike) ); // 1,2,something,else

배열 탐색

arr.indexOf , arr.lastIndexOf , arr.includes 와 같은 메서드는 문자열의 메서드와 동작 방법이 동일하다.

arr.find

arr.find 메서드는 함수를 인자로 받는다. 배열을 차례로 순회하면서 인자로 주어진 함수가 true를 리턴하면 종료하고 현재 값 (item) 을 반환한다.
true 반환이 없다면 undefined를 리턴한다.
함수 인자는 차례로 현재 인덱스의 값, 현재 인덱스, 배열 자기 자신 이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let result = arr.find(function(item, index, array) {
  // true가 반환되면 반복이 멈추고 해당 요소를 반환합니다.
  // 조건에 해당하는 요소가 없으면 undefined를 반환합니다.
});

/*
	일반적으로 아래와 같이 쓰인다.
*/
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

arr.filter

arr.find 는 인자로 주어진 함수가 true를 반환하면 즉시 종료되지만, arr.filter는 조건을 만족하는 모든 item을 모아 배열로 만들어 반환한다.
조건을 만족하는 요소가 없다면 빈 배열이 리턴된다.


배열을 변형하는 메서드

arr.map

함수를 인자로 받으며, 함수의 리턴값을 모아 배열로 반환한다.

1
2
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6

arr.sort([fn])

선택적으로 함수를 인자로 받으며, 배열의 요소를 정렬해주는 기능을 한다.
인자가 없다면 배열 내 요소를 문자열로 취급하여 오름차순 정렬한다.
숫자형으로 이루어진 배열을 내림차순 정렬하고 싶다면 아래와 같은 함수 인자를 건네주어야 한다.

1
2
3
4
let arr = [1,15,2,25];
let b = arr.sort(function(a,b) {return b - a;});
console.log(arr); // [25, 15, 2, 1]
console.log(b); // [25, 15, 2, 1]

이 때 주어진 함수를 comparator (compare 함수)라고 하며, comparator의 리턴값이 양수이면 b가 a보다 앞으로 오게끔 동작한다.
arr.sort는 리턴값으로 정렬된 배열을 제공하지만, 이미 본 배열이 변경된 상태이므로 리턴값은 잘 사용되지 않는다.

arr.reverse

배열을 역순으로 바꾸어주는 메서드이다.

str.split(delim) 과 arr.join(glue)

str.split(delim) 은 주어진 delim으로 문자열을 구분하여 각각의 요소를 합쳐 배열로 만들어 리턴한다.
arr.join(glue) 은 주어진 glue을 구분자로 하여 배열의 각 요소를 합친 문자열을 리턴한다.

arr.reduce와 arr.reduceRight

arr.reduce도 배열의 각 요소에 대해 연산을 수행하는 것은 동일하지만, 이전 요소의 결과값을 다음 요소의 연산에 사용할 수 있다는 점에서 차이가 있다.
인자로 주어지는 함수는 아래와 같은 형태를 갖는다.

1
2
3
let value = arr.reduce(function(accumulator, item, index, array) {
  // ...
}, [initial]);

다른 메서드와는 달리 accumulator라는 인자가 있다. 이 인자가 바로 이전 요소의 연산 결과값이다. [initial]은 선택적 인자로, 첫 번째 배열 요소의 accumulator로 주어진다.
가장 대표적인 사용 예시는 배열 요소의 누적합을 구하는 예시이다.

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

let result = arr.reduce((sum, current) => sum + current, 0);

alert(result); // 15

arr.reduce를 사용할 때 초기값 인자를 제공하는 편이 바람직하다.
위 코드에서 initial 인자를 주지 않아도 에러는 발생하지 않는다. initial 인자가 주어지지 않았을 경우, 배열의 첫 번째 요소를 초기값으로 설정하고 두 번째 요소부터 연산하기 때문이다.
만약 빈 배열을 대상으로 초기값 없이 이 메서드를 호출했다면, 에러가 발생한다.


Array.isArray

배열은 기본적으로 객체형이므로 typeof 연산자로는 배열인지 아닌지 구분할 수 없다.
이 때 Array.isArray(arg) 를 사용하면 배열인지 아닌지를 판단할 수 있다.


배열 메서드와 ‘thisArg’

sort를 제외한 대부분의 배열 메서드는 this 컨텍스트를 선택적으로 인자로 줄 수 있다.
thisArg를 인자로 주면, 함수 인자의 this에 thisArg가 할당된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

위 예시 코드에서 users.filter에 army 인자를 넘겨주지 않았다면?

canJoin() 함수가 실행되면서 함수의 기본 this (global 객체) 에서 minAge, maxAge 속성을 찾으려 할테고, 이들은 존재하지 않기 때문에 빈 배열이 soldiers 변수에 할당되고, soldiers[0].age 접근 시 에러를 출력하게 된다.

0%