라즈베리파이반

라즈베리파이 등 컴퓨터계열 게시판입니다.

제목자바스크립트: 배열 메소드2023-01-29 03:51
작성자user icon Level 4

88x31.png


이번 글에서는 자바스크립트에서 유용하게 사용할 수 있는 배열과 관련된 메소드를 알아보도록 하겠습니다. 


1. Array.prototype.forEach()


forEach() 메소드는 배열 요소들을 파라미터로 하여 각각 callback 함수를 호출하는 메소드입니다.


구문

arr.forEach(callback(currentvalue[, index[, array]])[, thisArg])


구문에서 보듯이 매개변수는 callback 함수와 thisArg를 받습니다.


callback 함수는 currentvalue, index, array를 인수로 하여 호출됩니다. currentvalue는 요소값, index는 인덱스, array는 배열객체를 나타냅니다.


forEach 예제

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


arr.forEach(function(e, i, a) {

  console.log(e, i, a);

})


출력 결과 

 


ES6의 화살표 함수를 통해 다음과 같이 코드를 작성할 수도 있습니다.


forEach 화살표 함수 사용

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


arr.forEach((e, i, a) => {

  console.log(e, i, a);

})


for 반복문 대신에 forEach를 사용하기도 하는데, 이 경우 forEach는 초기화 되지 않은 값에 대한 반복을 생략합니다.


for문과 forEach문 비교

const arr = [1, 2, 3, , 5];


console.log("for문:");

for (e of arr) console.log(e);


console.log("forEach 메소드:");

arr.forEach(e => console.log(e));


출력 결과 

 


4번째 요소가 초기화되지 않았는데, for문의 경우 undefined를 출력하게 되지만 forEah 메소드는 4번째 요소를 생략하여 출력되지 않습니다.




forEach 메소드는 배열의 복사본을 통해 요소를 순회하는 것이 아니라 원본 배열 자체의 인덱스를 순회합니다.


원본 배열 객체 사용

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


arr.forEach(e => {

  console.log(e);

  if (e === 3) arr.shift();

});


출력 결과 

 


위에 코드에 의하면 요소가 3이면 배열의 1번째 요소인 1을 제거하여 arr는 [2, 3, 4, 5] 가 됩니다. 원본 배열의 인덱스가 1씩 감소하는데, forEach 메소드는 반복 이전의 배열을 복사하지 않고 원본 배열을 그대로 사용하므로 4가 아니라 4번째 요소인 5가 출력된 후 반복이 종료됩니다.




forEach 메소드에서 2번째 파라미터인 thisArg를 설정하여 콜백함수의 this를 지정해 줄 수 있습니다.


콜백함수 this 설정

let result = 10;


const calculator = {

  result: 0,

  sum: function(arr) {

    arr.forEach(function(el) {

      this.result += el;

    }, this);

  }

}


calculator.sum([1, 2, 3]);

console.log(calculator.result);


출력 결과 

 


this에 대해 알 필요가 있는데, 메소드 내부에서 this는 메소드를 호출한 객체를, 함수에서 this는 전역객체인 globalThis를 바인딩합니다.


브라우저에서 globalThis는 window 객체를 가리키며, 만약 argThis를 설정하지 않았다면 전역변수 result에 1, 2, 3이 더해져 calculator의 result 프로퍼티는 그대로 0으로 남아 0이 출력되었을 것입니다.


그러나 위에 코드에는 argThis로 this를 설정했습니다. 메소드 내에서 this는 해당 메소드를 호출한 calculator 객체가 되며, calculator 객체의 프로퍼티인 result에 1, 2, 3이 더해져 6이 출력됩니다.



2. Array.prototype.map()


map() 메소드는 배열 내 모든 요소들에 대하여 호출한 콜백함수의 결과를 모아 새로운 배열을 반환하는 메소드 입니다.


구문

arr.map(callback(currentValue[, index[, array]])[, thisArg])


매개변수는 forEach 메소드와 동일합니다. 아래 코드는 각 요소의 제곱수를 모은 배열을 출력합니다.


map 예제

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

square = arr.map(e => e**2);


console.log(square);


출력 결과 

 


map을 사용하여 프로그래머스 문제를 하나 풀어보도록 하겠습니다.


문제


풀이 

const morse = {

  '.-':'a','-...':'b','-.-.':'c','-..':'d','.':'e','..-.':'f',

  '--.':'g','....':'h','..':'i','.---':'j','-.-':'k','.-..':'l',

  '--':'m','-.':'n','---':'o','.--.':'p','--.-':'q','.-.':'r',

  '...':'s','-':'t','..-':'u','...-':'v','.--':'w','-..-':'x',

  '-.--':'y','--..':'z'

}


function solution(letter) {

  return letter.split(' ').map(e => morse[e]).join('');

}


console.log(solution(".... . .-.. .-.. ---"));


출력 결과 


우선 split 함수를 통해 문자열 .... . .-.. .-.. ---을 공백을 기준으로 분리하면 ['....', '.', '.-..', '.-..', '---'] 배열이 생성됩니다.


해당 배열을 map을 통하여 모스부호에 해당하는 알파벳을 리턴하고, join 함수를 통해 배열을 문자열로 바꾸면 hello라는 문자열이 출력됩니다.



3. Array.prototype.reduce()


reduce() 메소드는 배열의 각 요소에 대하여 리듀서(reducer) 함수를 실행하여 하나의 결과값을 반환하도록 하는 메소드 입니다.


구문

arr.reduce(callback[, initialValue])


매개변수는 callback 함수와 initialValue를 받습니다.


callback 함수는 accumulator, currentValue, currentIndex, array를 인수로 하여 호출됩니다. accumulator는 콜백 반환값을 누적하는 누산기, currentValue는 현재 처리할 요소, currentIndex는 현재 요소의 인덱스, array는 호출된 배열을 나타냅니다.


reduce 예제

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

result = arr.reduce((acc, cur) => acc + cur);


console.log(result);


출력 결과 

 


누산기인 acc에는 리듀서 함수의 반환값이 할당됩니다. 리듀서 함수는 누산기 값과 현재 요소의 값을 더한 값을 반환합니다. 그러므로 최종적으로 누산기에는 배열에 있는 모든 값을 더한 값(1 + 2 + 3 + 4 + 5 = 15)이 할당됩니다.




initialValue는 누산기의 초기값을 나타냅니다. 만약 누산기의 초기값을 설정하지 않는다면 배열의 1번째 요소가 누산기의 초기값이 되며, 리듀서 함수는 2번째 요소부터 수행되므로 복잡한 연산의 경우 최종적인 누산기값이 의도하는 값과 다르게 나올 수 있습니다.


초기값을 설정하지 않은 경우

console.log([2,3,4].reduce((acc,cur) => acc + cur**2))


2, 3, 4의 제곱값을 더한 값을 출력하려는 경우, 의도하는 값은 29가 되어야 합니다. 하지만 위의 코드와 같이 초기값을 주지 않는다면 27이 출력됩니다.


올바른 값을 얻으려면 아래와 같이 초기값을 0으로 설정해줍니다.


초기값을 설정한 경우

console.log([2,3,4].reduce((acc,cur) => acc + cur**2, 0))


reduce 메소드는 차원을 축소하는 연산에 많이 사용되므로 잘 사용한다면 복잡한 문제를 간단하게 해결할 수 있습니다.


문제

 


풀이 

function solution(hp) {

  return [5,3,1].reduce((a,c) => {

    const count = a+(hp/c|0);

    hp %= c;

    return count;

  }, 0)

}


복잡해보이지만 각 요소의 몫은 개미의 수가 되고, 몫에 대한 나머지는 남은 체력이 됩니다. 그러므로 체력이 0이 될때까지 몫을 더해가면 사냥에 필요한 최소 개미수가 됩니다.

#자바스크립트# forEach# map# reduce
댓글
자동등록방지
(자동등록방지 숫자를 입력해 주세요)