[자바스크립트 기초-8] Array 기본 메소드-2

[자바스크립트 기초-8] Array 기본 메소드-2

지난 포스팅에 이어 이번 포스팅에서도 기본 메소드에 대해 알아보도록 하겠습니다.


#알파벳 순서대로 정렬

Array의 아이템들을 알파벳 순서대로 정렬할 땐 sort()를 쓰면 됩니다.

var arr = ["Bear", "Cat", "Ant", "Elephant", "Dog"];

arr.sort();
console.log(arr);
// 결과 -> ["Ant", "Bear", "Cat", "Dog", "Elephant"]

한글도 가나다 순서로 정렬 할 수 있을까요?

var arr = ["나비", "가지", "다람쥐", "마늘", "하마"];

arr.sort();
console.log(arr);
// 결과 -> ["가지", "나비", "다람쥐", "마늘", "하마"]

됩니다.

역순으로 정렬하고 싶을 땐 reverse()를 쓰면 됩니다. reverse()는 현재 array의 아이템들을 거꾸로 정렬해주는 메소드입니다. 알파벳이나 가나다순과는 전혀 상관이 없습니다. 그렇기 때문에 가나다를 역순으로 정렬하고 싶을 땐 우선 sort()를 실행한 후 reverse()를 사용하면 됩니다.

var arr = ["나비", "가지", "다람쥐", "마늘", "하마"];

arr.sort();
arr.reverse();
console.log(arr);
// 결과 -> ["하마", "마늘", "다람쥐", "나비", "가지"]

Array의 아이템 수가 적을 땐 sort()reverse() 모두 크게 지장을 느낄 정도의 속도는 느끼지 못하지만, 아이템 수가 엄청나게 많을 땐, 컴퓨터의 성능에 따라서는 퍼포먼스에 영향을 크게 받는다고 하니, 이 점을 기억해두면 좋을 것 같습니다.

#Array에 반복해서 함수 적용

Array의 각 아이템에 대하여 반복해서 같은 함수를 적용하고 싶은 경우가 있습니다. 보통 for loop를 사용하는데 우선 for loop를 이용한 방법을 알아보겠습니다.

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

// arr.length는 arr의 길이를 알아내는 메소드. 
// arr의 아이템이 다섯개이기 때문에 5가 됩니다.

// arr의 각 아이템의 포지션은 0부터 시작하기 때문에 i를 0부터 시작해줍니다.
// i가 arr.length (5) 보다 작은 숫자일 때 i에 1을 더해가며 계속 반복됩니다.
for (var i = 0; i < arr.length; i++) {
    arr[i] = arr[i] * 2;
}

console.log(arr);
// 결과 -> [2, 4, 6, 8, 10]

Array안에 있는 모든 숫자를 2배로 해주는 예제 코드를 적어봤습니다. 이렇게 for loop를 사용해서 해도 되지만, Array에는 자체적인 forEach()라는 메소드가 있기 때문에 다음 예제에서는 그걸 사용해봅니다.

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

// value는 arr의 각 아이템
// index는 arr의 해당 아이템의 포지션 번호
// array는 forEach()를 실행하는 array (이번 경우는 arr)
// value, index, array의 인풋들은 순서만 지키면 될 뿐, 
// 이름은 임의로 본인이 원하는 것으로 지정가능합니다.
arr.forEach(function(value, index, array) {
    array[index] = value * 2;
});

console.log(arr);
// 결과 -> [2, 4, 6, 8, 10]

같은 결과가 나온 걸 알 수 있습니다.

#메소드 실행 후 새로운 Array를 생성

forEach()와 비슷한 map() 메소드를 알아보겠습니다.

var arr = [1,2,3,4,5];
var arr2 = arr.map(function(value, index, array) {
    return value * 2
});

console.log(arr);
// 결과 -> [1, 2, 3, 4, 5]

console.log(arr2);
// 결과 -> [2, 4, 6, 8, 10]

map()을 실행한 array의 각 아이템에 대해 특정 함수를 적용한 후 새로운 array를 생성합니다. 그렇기 때문에 함수에 반드시 return을 포함해줘야합니다. 그것이 forEach()와의 가장 큰 차이입니다.

참고로 ES6부터 새로 추가된 arrow function에선 return 코드 외의 다른 코드가 없을 때만 예외적으로 return을 생략할 수 있습니다.

var arr = [1,2,3,4,5];
var arr2 = arr.map((value, index, array) => value * 2);

console.log(arr);
// 결과 -> [1, 2, 3, 4, 5]

console.log(arr2);
// 결과 -> [2, 4, 6, 8, 10]

이건 딱히 map()에만 해당되는게 아니고 모든 함수에 대해 동일합니다. ES6의 arrow function이 어떻게 사용되는지에 따른 것입니다. arrow function에 대해서는 다른 포스팅에서 다루도록 하겠습니다.

#Array에 필터 적용하기

Array에 포함된 아이템들 중에, 특정 조건을 충족하는 아이템들만 뽑아서 새로운 array를 만들 수 있습니다. filter() 메소드를 이용하면 됩니다.

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.filter(function(value, index, array) {
    // 3보다 큰 숫자들만 뽑아냅니다.
    return value > 3;
});

console.log(arr);
// 결과 -> [1, 2, 3, 4, 5]

console.log(arr2);
// 결과 -> [4, 5]

예제에서는 3보다 큰 숫자를 뽑아서 새로운 array를 생성했습니다. 새로운 array를 생성하는 메소드이기 때문에, 사용할 조건 함수에 return을 포함시켜주는 것은 필수입니다.

#Array의 아이템들을 이용하여 하나의 값 만들기

Array의 값들을 이용하여 하나의 값을 도출할 땐 reduce()라는 메소드가 있습니다.

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

// total은 직전에 return된 값을 불러옵니다.
var sum = arr.reduce(function(total, value, index, array) {
    return total + value;
});

console.log(arr);
// 결과 -> [1, 2, 3, 4, 5]

console.log(sum);
// 결과 -> 15

위의 예제에서는 reduce()를 사용하여 arr에 있는 숫자들의 합을 구해보았습니다. 앞서 봤던 map()filter()와 다른점은 조건 함수에 인풋이 추가되었다는 점이죠. 가장 처음에 오는 인풋은 직전에 return된 값을 보유하고 있습니다.

reduce() 메소드가 실행되면 처음에 total은 아무 값이 없습니다. 그렇기 때문에 첫번째는 "total + 1" return 값이 1이 됩니다. 두번째 아이템을 불러왔을 때 total의 값은 1이기 때문에, return 값은 "1 + 2"의 합인 3이 됩니다. 마찬가지로 세번째 아이템을 불러왔을 때 total의 값은 3이기 때문에, return 값은 "3 + 3"의 합인 6이 됩니다. 이런식으로 반복되어 마지막 return 값인 15가 sum이라는 변수에 저장됩니다.

#Array의 아이템들이 특정 조건을 충족하는지 확인

우선 Array에 포함되어있는 모든 아이템들이 특정 조건을 충족하는지 확인하기 위해선 every()라는 메소드를 사용하면 됩니다.

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

var test = arr.every(function(value, index, array) {
    // 모든 값들이 2보다 큰지 확인
    return value > 2;
});

console.log(test);
// 결과 -> false

var test2 = arr.every(function(value, index, array) {
    // 모든 값들이 0보다 큰지 확인
    return value > 0;
});

console.log(test2);
// 결과 -> true

every() 메소드의 결과 값은 true 혹은 false 입니다. 조건 함수에 return을 까먹고 안쓰면 값이 항상 false로 나오기 때문에 주의해야합니다.

하나라도 충족

Array의 아이템들 중에 하나라도 조건을 충족하는 아이템이 있는지 확인하고 싶을 땐 some() 메소드를 사용하면 됩니다.

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

var test = arr.some(function(value, index, array) {
    // 2보다 큰 값이 하나라도 있는지 확인
    return value > 2;
});

console.log(test);
// 결과 -> true

var test2 = arr.some(function(value, index, array) {
    // 5보다 큰 값이 하나라도 있는지 확인
    return value > 5;
});

console.log(test2);
// 결과 -> false

every()와 마찬가지로 some()true혹은 false 값을 돌려줍니다. return을 까먹고 쓰지 않으면 항상 false 값이 나오기 때문에 주의해야합니다.

조건을 충족하는 아이템의 포지션

특정 조건을 충족하는 첫번째 아이템의 값을 알고 싶으면 find() 메소드를 이용하면 됩니다.

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

var test = arr.find(function(value, index, array) {
    return value > 2;
});

console.log(test);
// 결과 -> 3

위의 예제에서는 조건을 2보다 큰 값으로 지정해줬는데, 해당되는 값은 "3, 4, 5"로 세가지 있습니다. find() 메소드는 가장 처음 조건을 충족한 값을 돌려줍니다.

#특정 아이템의 포지션을 알고 싶을 때

Array안에 포함된 아이템들 중에 특정 아이템이 어느 포지션에 있는지 알고 싶을 땐 indexOf() 메소드를 사용합니다.

var arr = ["나비", "가지", "다람쥐", "마늘", "다람쥐"];

var num = arr.indexOf("다람쥐");
console.log(num);
// 결과 -> 2

console.log(arr[num]);
// 결과 -> 다람쥐

// Array안에 지정한 아이템이 없을 땐 -1 됩니다.
var num2 = arr.indexOf("사과");
console.log(num2);
// 결과 -> -1

Array의 포지션은 0부터 시작한다는 것을 기억하고 사용하면 됩니다. Array안에 지정한 아이템이 없을 경우엔, 없다는 뜻으로 -1을 결과값으로 돌려줍니다.

예제에서도 알 수 있듯이, "다람쥐"가 2번포지션과 4번포지션에 중복되게 있는 경우가 있을 수 있는데, indexOf()는 앞에서부터 검색을 하기 때문에, 먼저 발견된 포지션을 알려줍니다.

검색을 시작 할 포지션을 지정해줄 수도 있습니다.

var arr = ["나비", "가지", "다람쥐", "마늘", "다람쥐"];

var num = arr.indexOf("다람쥐", 3);
console.log(num);
// 결과 -> 4

indexOf() 메소드의 첫번째 인풋은 검색할 아이템, 그리도 두번째 인풋은 검색을 시작할 포지션을 지정할 수 있습니다. 위의 예제의 경우는 3번 포지션을 지정해줬기 때문에, 검색은 "마늘"부터 시작됩니다. 그렇기 때문에 4번 포지션에 있는 다람쥐가 가장 먼저 발견된 아이템이 되어 결과 값이 4가 된거죠.

빈공간(empty)의 경우

그렇다면 Array에 빈공간(empty)이 있는지 확인하고 싶을 경우엔 어떻게 해야할까요?

var arr = [];
arr[1] = "감자";

console.log(arr);
// 결과 -> [empty, "감자"]

console.log(arr.indexOf(empty));
// 에러

console.log(arr.indexOf(undefined));
// 결과 -> -1

console.log(arr.includes(undefined));
// 결과 -> true

위의 예제에서 볼 수 있듯이 indexOf()empty를 검색하면 에러가 납니다. 그 이유는 empty를 빈공간이란 뜻이 아니고 변수의 하나로 인식하기 때문입니다. 그래서 지정이 안되었다라는 뜻의 undefined로 검색을 해보았지만 결과는 찾지 못하였다는 뜻의 -1이 나왔습니다.

그래서 includes()라는 메소드를 썼습니다. 이건 지정한 값이 array에 있다면 true, 아니라면 false 값을 돌려주는 메소드입니다. includes()는 ES6부터 추가된 새로운 메소드로, array안의 빈공간(empty)을 undefined로 인식해주기 때문에, 빈공간이 있나 없나 확인하고 싶을 땐 이 메소드를 이용하면 됩니다.

뒤에서부터 검색

indexOf() 처럼 앞에서부터 검색하는게 아니고 뒤에서부터 검색을 하고 싶을 땐 lastIndexOf() 메소드를 사용하면 됩니다. 사용법은 indexOf()와 동일하기 때문에 예제는 딱히 적지 않겠습니다.

특정 조건을 충족하는 아이템의 포지션

특정 조건을 가장 먼저 충족하는 아이템의 포지션을 구하고 싶을 땐 findIndex() 메소드를 사용하면 됩니다.

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

var test = arr.findIndex(function(value, index, array) {
    return value > 2;
});

console.log(test);
// 결과 -> 2

위의 예제에서는 2보다 큰 숫자를 가장 먼저 충족하는 아이템의 포지션을 구하고 있습니다. 가장 먼저 충족하는 값은 3이기 때문에, 3의 포지션인 2가 결과 값으로 돌아오게 됩니다.


이렇게 두번의 포스팅에 나누어 Array의 기본 메소드에 대해 알아보았습니다. 기본적으로 내제되어 있는 메소드만으로도 많은 일을 할 수 있습니다.

다만 Array에 너무 많은 아이템이 들어있는 경우, 기본 메소드를 사용하는 것보다 본인이 직접 더 정교한 함수를 적어서 쓰는게 실행 속도가 더 빠른 경우도 있기 때문에, 상황에 맞게 사용하면 됩니다.