본문 바로가기

JavaScript

JavaScript: 배열 내장함수 (forEach, map, indexOf, findIndex, find, filter, splice, splice, shift, pop, unshift, push, concat, join, reduce)

반응형

1. forEach

배열 안에 있는 원소들을 가지고 어떤 작업을 일괄적으로 하고 싶을 때, forEach문을 사용해 간결한 코드를

작성할 수 있다.

 

const superheroes = ['아이언맨', '캡틴 아메리카', '토르', '닥터 스트레인지']

for(let i = 0; i<superheroes.length;i++){
  console.log(superheroes[i]);
}

배열의 요소들을 출력하기 위해 다음과 같이 작성해야 했다면

 

const superheroes = ["아이언맨", "캡틴 아메리카", "토르", "닥터 스트레인지"];

function print(hero) {
  console.log(hero);
}

superheroes.forEach(print);

forEach문을 이용해 다음과 같이 작성할 수 있다.

 

const superheroes = ["아이언맨", "캡틴 아메리카", "토르", "닥터 스트레인지"];

superheroes.forEach(function(hero) {
  console.log(hero);
});

위에서는 'print'라는 함수를 위에서 선언했는데 다음과 같이 파라미터를 넣을 때 바로 함수를 선언할 수도 있다.

 

const superheroes = ["아이언맨", "캡틴 아메리카", "토르", "닥터 스트레인지"];

superheroes.forEach((hero) => {
  console.log(hero);
});

더 나아가 화살표(arrow) 함수를 사용할 수도 있다.

 

2. map

map 함수는 배열안의 모든 원소를 변환할 때 사용한다.

 

const array = [1, 2, 3, 4, 5, 6, 7, 8];

const squared = [];
for (let i = 0; i < array.length; i++) {
  squared.push(array[i] * array[i]);
}

console.log(squared);

주어진 배열을 제곱하고 출력하기 위해서는 다음과 같이 작성할 수 있다.

 

const array = [1, 2, 3, 4, 5, 6, 7, 8];

const squared = [];
array.forEach((number) => {
  squared.push(number * number);
});

console.log(squared);

이를 forEach를 이용하면 다음과 같다. 이것도 충분히 괜찮지만 'map' 함수를 사용해 더 깔끔하게 작성할 수 있다.

 

const array = [1, 2, 3, 4, 5, 6, 7, 8];

const suqare = (n) => n * n;
const squared = array.map(square);

console.log(squared);

다음과 같이 'map' 함수를 사용할 수 있다.

 

const array = [1, 2, 3, 4, 5, 6, 7, 8];

const squared = array.map((n) => n * n);

console.log(squared);

이전 코드블록에서 square 함수를 선언하는 것 대신 함수 자체를 map 함수 안에 넣어줄 수도 있다.

 

map 같은 경우는 배열의 요소들을 전체적으로 변환해주고 싶을 때 사용하는 배열 내장함수이다.

 

배열 안에 객체가 있는 경우를 가지고 위의 내용을 활용해 보자.

 

const items = [
  {
    id: 1,
    text: "hello",
  },
  {
    id: 2,
    text: "bye",
  },
];

다음과 같이 객체를 성분으로 가진 배열이 있다.

이 배열을 'text' 로만 이루어진 문자열 배열로 바꾸기 위해서는

 

const texts = items.map((item) => item.text);
console.log(texts);

다음과 같이 작성하면 된다.

[ 'hello', 'bye' ]

결과는 다음과 같다.

 

3. indexOf

'indexOf' 함수는 원하는 항목이 배열 내에서 어디 위치하는지 알려주는 함수이다.

 

const superheroes = ["아이언맨", "캡틴 아메리카", "토르", "닥터 스트레인지"];
const index = superheroes.indexOf("토르");

console.log(index);

 

2

이런 식으로 특정항목이 배열에서 몇 번째 원소인지 알고 싶다면 indexOf 함수를 사용할 수 있다.

 

4.  findIndex

만약 배열 안의 값들이 객체이거나, 조건으로 값을 찾고자 한다면 indexOf 함수로는 할 수 없다.

 

const todos = [
  {
    id: 1,
    text: "자바스크립트 입문",
    done: true,
  },
  {
    id: 2,
    text: "함수 배우기",
    done: true,
  },
  {
    id: 3,
    text: "객체와 배열 배우기",
    done: true,
  },
  {
    id: 4,
    text: "배열 내장함수 배우기",
    done: false,
  },
];

다음과 같이 객체로 이루어진 배열에서 id가 3인 경우의 위치를 찾고 싶을 때 indexOf 함수로는 불가능하다.

이 경우 'findIndex' 함수를 사용해야 한다.

findIndex 함수에 넣는 파라미터는 함수이다. 특정 조건을 확인해서 그 조건이 일치하면, 일치하는 원소가 몇 번째인지 알려준다.

 

const index = todos.findIndex((todo) => todo.id === 3);
console.log(index);
2

다음과 같이 findIndex 함수를 사용해 id가 3인 객체의 위치를 찾을 수 있다.

 

배열 안에 있는 값들이 객체이거나 특정 조건을 확인해야 하는 경우에는 'findIndex' 함수를 사용하자.

 

5. find

find 함수는 findIndex 함수와 비슷하다. 다른 점은 findIndex는 몇 번째인지 알려준다면 find는 객체 자체(숫자, 원소)를 반환한다.

const todo = todos.find((todo) => todo.id === 3);
console.log(todo);
{ id: 3, text: '객체와 배열 배우기', done: true }

 

6. filter

'filter' 함수는 특정 조건을 만족하는 원소들을 찾아서 그 원소들을 가지고 새로운 배열을 만드는 것이다.

 

const tasksNotDone = todos.filter((todo) => todo.done === false);
console.log(tasksNotDone);
[ { id: 4, text: '배열 내장함수 배우기', done: false } ]

다음과 같이 'done' 이 false인 경우만 필터링할 수 있다. 이는 기존의 배열을 건드리지 않고 새로운 배열을 만들어낸다.

 

const tasksNotDone = todos.filter((todo) => !todo.done);
console.log(tasksNotDone);

위 코드를 더 간단히 해보면 다음과 같다. 

filter는 아주 유용하니 잘 숙지해두자.

 

7. splice와 slice

splice는 배열에서 특정 항목을 제거할 때 사용한다. 

 

const numbers = [10, 20, 30, 40];
const index = numbers.indexOf(30);
numbers.splice(index, 1);
console.log(numbers);
[ 10, 20, 40 ]

numbers 배열에서 30이 삭제된 것을 확인할 수 있다.

여기서 splice 함수는 제거된 배열을 결괏값으로 가지게 된다.

 

const numbers = [10, 20, 30, 40];
const index = numbers.indexOf(30);
const spliced = numbers.splice(index, 2);
console.log(spliced);
console.log(numbers);
[ 30, 40 ]
[ 10, 20 ]

결과는 다음과 같다.

 

slice함수는 배열을 잘라내는 데 사용한다. splice와 차이점은 기존의 배열을 건드리지 않는다는 것이다. 넣어주는 파라미터 값도 조금 다르다.

 

const numbers = [10, 20, 30, 40];

const sliced = numbers.slice(0, 2);
console.log(sliced);
console.log(numbers);

 

splice 함수는 기존의 배열을 수정하지만 slice 함수는 기존의 배열을 건드리지 않는다.

 

 

8. shift, pop, unshift, push, concat, join

shift는 첫 번째 원소를 배열에서 추출해준다. 추출된 함수는 배열에서 삭제된다.

shift는 맨 앞에 있는 원소를 하나씩 꺼내 주는 역할을 한다.

만약 다 꺼내어 빈 배열이 됐는데 다시 shift를 하면 오류는 발생하지 않고 빈 배열로 남아있게 된다.

const numbers = [10, 20, 30, 40];

const value = numbers.shift();
console.log(value);
console.log(numbers);
10
[ 20, 30, 40 ]

 

pop은 shift와 비슷하다. pop은 배열의 맨 뒤부터 하나씩 꺼낸다.

const numbers = [10, 20, 30, 40];

const value = numbers.pop();
console.log(value);
console.log(numbers);
40
[ 10, 20, 30 ]

 

unshift는 배열의 맨 앞부분에 추가하는 것이다.

const numbers = [10, 20, 30, 40];
numbers.unshift(5);
console.log(numbers);
[ 5, 10, 20, 30, 40 ]

 

push는 배열의 맨 뒷부분에 추가하는 것이다.

const numbers = [10, 20, 30, 40];
numbers.push(50);
console.log(numbers);
[ 10, 20, 30, 40, 50 ]

 

shift와 unshift가 하나의 짝이고 pop과 push가 하나의 짝이다.

이 네 가지 함수 모두 배열을 수정한다는 것을 기억하자.

 

const arr1 = [1,2,3]
const arr2 = [4,5,6]

const concated = arr1.concat(arr2)

concat 함수는 여러 개의 배열을 합쳐준다. 기존의 배열은 건드리지 않는다.

 

const array = [1, 2, 3, 4, 5];
console.log(array.join());
console.log(array.join(" "));
console.log(array.join(", "));
1,2,3,4,5
1 2 3 4 5
1, 2, 3, 4, 5

join 함수는 배열 안의 값들을 문자열 형태로 합쳐줄 때 사용한다. 다음과 같이 배열을 문자열로 만들 수 있다.

 

9. reduce

reduce 함수는 잘 사용한다면 정말 유용한 함수다. 이 함수는 주로 배열이 주어졌을 때 배열 안의 모든 값을 사용하여

연산을 해야 할 때 사용한다.

 

const numbers = [1, 2, 3, 4, 5];

let sum = 0;
numbers.forEach((n) => {
  sum += n;
});

console.log(sum);

 

 

15

배열 요소들의 합을 출력하는 코드이다.

reduce 함수를 사용하면 이를 한 줄로 작성할 수 있다.

 

const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum);
15

다음과 같다. 

이 코드가 어떻게 작동하는지 살펴보자 먼저, accumulator는 누적된 값을 뜻하고 current는 각 원소들을 뜻한다.

세 번째 줄 마지막에 있는 0이 초기 accmulator가 되고 current에는 배열의 첫 번째 값인 1이 들어간다. 

다음으로 화살표 함수가 실행되어 0 + 1 이 실행되고 그 결과인 누적된 값은 accumulator에 들어간다.

다시 current에는 2가 들어가고 결과는 accumulator에 들어가는 방식으로 진행된다.

 

reduce는 index와 array도 파라미터로 받아올 수 있다.

index는 index 말 그대로 배열의 각 원소가 몇 번째 원소인지 알려주고  array는 함수를 실행하고 있는 배열 자신을 의미한다.

 

const numbers = [1, 2, 3, 4, 5];

const avg = numbers.reduce((accumulator, current, index, array) => {
  if (index === array.length - 1) { // index가 배열의 마지막을 가리킨다면
   
    return (accumulator + current) / array.length;
  }
  return accumulator + current;
}, 0);
console.log(avg);
3

reduce 함수를 사용해 배열 원소들의 평균을 구하는 코드이다. 

먼저, accumulator 에는 0, current에는 1, index에는 0, array에는 numbers 배열이 들어가고 if문은 실행하지 않고

둘의 합을 리턴한다. 그러다가 index가 4가 되면 if문이 실행되어 누적된 값을 가진 accumulator와 5를 가진 current가  더 해지고 파라미터로 받아온 array의 길이를 나누어 평균을 리턴하게 된다.

 

reduce라는 함수는 기존의 함수들 보다 사용하는 방법이 어려울 수 있지만, 작동 방식을 완벽하게 이해하고 나면

정말 다양하게 써먹을 수 있다. 잘 숙지해두고 활용할 수 있도록 하자.

 

const alphbets = ["a", "a", "a", "b", "c", "c", "d", "e"];
const counts = alphbets.reduce((acc, current) => {
  if (acc[current]) {
    acc[current] += 1;
  } else {
    acc[current] = 1;
  }
  return acc;
}, {});

console.log(counts);
{ a: 3, b: 1, c: 2, d: 1, e: 1 }

다음 코드는 알파벳의 개수를 카운트해주는 코드이다. acc에 초기 값으로 비어있는 객체를 주고

acc[current] (= acc.current)가 없다면 1로 초기화해주고 있다면 1을 증가시켜 주는 방식으로 카운트를 한다.

 

이런 방식으로도 사용할 수 있다니 쓸 곳이 정말 많겠다는 생각이 들었다.

반응형