Medium - Avoid Writing Another For-Loop in JavaScript

원문 - Zeng Hou Lim

Trend 파악을 위한 Medium 기고문 포스팅 - 자바스크립트에서 또 다른 For-Loop 작성을 피하는 법; 코드의 가동성을 향상시키는 7가지 Higher-Order 함수

Photo by Priscilla Du Preez on Unsplash

신입 개발자로서 대부분 우리는 작은 것들을 모아서 구성을 하려는 습성이 있고 코드를 더욱 세밀하게 제어하고 싶어합니다. 배열이나 자바스크립트의 객체로 작업을 할 때 신입 개발자 중 일부는 for 루프를 사용해서 배열의 요소를 순회하거나 로직의 중요한 핵심 요소로 사용할 것입니다. 글쎄요, 그렇게 작업하는 것이 꼭 잘못된 것은 아니죠(컴공에서 처음으로 배우는 루프 제어문이 for문이므로;) 그러나 자바스크립트에는 고차원 함수가 내장되어 있기 때문에 우리의 코드를 더 우아하고 가독성 있게 만들고 DRY하게 만들 수 있습니다.

What Is a Higer-Order Function

고차원 함수(higher-order function)이란 함수를 매개변수로 받거나 함수를 리턴하는 것을 말합니다. 여기서는 일곱가지의 고차원 함수를 보여들릴 것입니다. 각 섹션에서 언제, 어떻게 이 함수들을 사용해야 하는지 알려드리겠습니다.

1.forEach()

forEach() 메소드는 배열안에 모든 요소에 대해서 전달받은 함수를 실행합니다.

When to use it

forEach()는 일반적으로 많은 상황에서 사용되며 다른 고차함수들에 의해 커버되는 것도 있습니다. 그러나 특정 고차함수들로 구현할 수 있다면 forEach()대신에 해당 고차함수를 사용해야 합니다. 나중에 해당 고차함수 섹션에서 더욱 자세히 설명드리겠습니다.

Syntax

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

기본적으로 forEach에 전달될 필요가 있는 함수는 currentValue로 순회할 대상입니다. 아래의 예제에서는 elem이라고 명명되었습니다. 나머지는 선택적인 파라미터 들입니다.

Example

const array = ['a', 'b', 'c'];
array.forEach(function(elem) {
    // using template literals here
    console.log(`Printing ${elem}`);
})

옵셔널 매개변수들을 어떻게 사용하는지 알고싶다면 아래의 비슷한 예제를 참고하세요

const array = ['a', 'b', 'c'];
array.forEach(function (elem, index, array) {
    console.log(`${elem} is at position ${index} of [${array}]`);
});
// a is at position 0 of the array [a, b, c]

추가적으로 this의 값을 전달해서 forEach에서 함수의 스코프로 사용할 수 있습니다.

const array = ['a', 'b', 'c'];
array.forEach(function(elem, index, array) {
    console.log(array == this); // checking for pointer equality
}, array); // pass in `this` as optional param

2.reduce()

When to use it

reduce()는 엄청나게 강력한 메소드로 리듀서 함수를 실행하여 배열의 값을 단일 값으로 줄일 수 있습니다. 이러한 소리가 복잡하게 들릴 수도 있는데 아이디어는 현재의 값을 순회하며 가산기의 값을 통합하여 각 순회마다 작업을 진행하는 것입니다. 이 설명이 여전히 복잡하다면 예제에서 빛을 찾으실 수 있을겁니다. 시험의 영역별로 점수를 저장하고 있는 객체가 있고 총점을 얻으려고 합니다. 단일 값을 원하기 때문에 reduce()가 여기에 적합한 메소드입니다.

Syntax

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

Example

const scoresBySection = {
  math: 60,
  reading: 70,
  writing: 87,
};

const sectionNames = Object.keys(scoresBySection);
const marks = sectionNames.reduce(function(accumulator, sectionName){
  // the return value will be accumulator for next iteration
    return accumulator + scoresBySection[sectionName];
}, 0) // initial value

console.log(marks) // 217

3.map()

When to use it

배열을 수정해야 할 필요가 있는 경우 forEach를 사용할 수도 있습니다.

Syntax

var new_array = arr.map(function callback(currentValue[, index[, array]]) { // return element for new array }[, thisArg])

Example

const array = [1, 2, 3];
array.forEach(function(elem, index, array) {
  array[index] = elem * 2;
});

console.log(array); // [2,4,6]

가능하다면 forEach() 대신에 다른 고차원 함수를 항상 써야했다고 한걸 기억하시나요? 존재하는 배열의 원소 하나하나에 변환을 하고 싶다면 map()을 사용해야 합니다. 해당 함수는 현재 값들을 전달하고 새로운 배열을 리턴합니다.

let array = [1,2,3];
array = array.map(function(elem) {
  return elem * 2;
})

console.log(newArray); // [2,4,6]

여기서 기억해야 할 중요한 점은 map()으로부터 새로운 배열을 받아야 하기 때문에 const 대신에 let으로 선언을 했다는 것입니다.

4.filter()

When to use it

우리가 항상 배열 안에 모든 값들을 원하지는 않습니다. 때로는 조건에 충족하는 요소들만 원하죠. filter를 사용하면 원본 배열에서 조건에 맞는 부분원소를 가져올 수 있습니다. map()과 마찬가지로 filter()는 새로운 배열을 리턴합니다.

Syntax

var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

Example

const array = [1,2,3,4,5];
const evenNumbers = array.filter(function(elem) {
  //expressions that return true are retained
  return elem % 2 == 0;
});

5.find()

When to use it

배열에서 원소를 찾는 작업은 건초더미에서 바늘을 찾는 것처럼 할 필요는 없습니다. find()는 조건에 만족하는 원소가 있다면 첫번째로 일치하는 원소를 리턴합니다. 한번 원소를 찾게되면 그 즉시 리턴됩니다.

Syntax

arr.find(callback(element[, index[, array]])[, thisArg])

Example

const array = [1,4,4,5];
const result = array.find(function(elem, index) {
  console.log(`Index: ${index}`);
  return elem === 4;
});
console.log(`Result: ${result}`);

// Index: 0
// Index: 1
// Result: 4

6.some()

When to use it

때로 우리는 배열에 조건을 만족하는 원소가 최소한 하나라도 있는지 알고 싶어합니다. some() 메소드는 그런 원소가 배열에 있는지 아닌지를 불린 값으로 알려줍니다.

Syntax

arr.some(callback(element[, index[, array]])[, thisArg])

Example

const array = [1,4,4,5];
const hasAtLeastAFour = array.some(function(elem) {
  return elem === 4;
});
console.log(hasAtLeastAFour);

// true

7.every()

When to use it

끝으로 우리는 배열이 특정 조건을 모두 만족하는지 알고 싶습니다. 이처럼 every()는 모든 요소가 조건을 만족하면 참을 리턴하고 아니면 거짓을 리턴합니다.

Syntax

arr.every(callback(element[, index[, array]])[, thisArg])

Example

const array = [1,4,4,5];
const allFours = array.every(function(elem) {
  return elem === 4;
});
console.log(allFours);

// false

Summary

  • For 루프를 대체할 수 있는 고차원 함수
  • 고차 함수를 사용해서 문제를 푸는 것이 가독성을 높여주고 더 우아하게 문제를 풀수 있기 때문에 되도록 고차함수를 쓰도록 하자.
  • forEach 대신에 다른 고차함수를 쓸 수 있다면 해당 고차함수를 쓰도록 하자.

© 2019. All rights reserved.

Powered by Hydejack v8.1.1