Electronic Jeremy Record

[Javascript] 배열 앞뒤값을 활용하는 Array.prototype.reduce 본문

기술의기록

[Javascript] 배열 앞뒤값을 활용하는 Array.prototype.reduce

Jeremy Winchester 2022. 2. 4. 16:50
반응형

이전 글에 Javascript 7개의 반복 함수에 대해 포스팅을 한 적이 있다. 

https://jeremyrecord.tistory.com/7?category=1046615 

 

[Javascript]배열 내장 반복 함수(Prototype) 7개 정리(forEach,map,filter,some,every,find,findIndex)

코딩을 할 때 반복문은 빠질 수 없는 신텍스다 대부분을 for 문법을 통해 하는게 가장 익숙한 방법이지만 javascript에서 친절(?) 하게 사용할 수 있는 다른 반복문들이 있다. for 조합되는 for in, for of

jeremyrecord.tistory.com

이번에도 마찬가지로 Javascript의 반복 함수지만

기존과는 조금 다르다.

일반적으로 반복 함수는 해당 value 또는 index를 반복한다. 

하지만 이 함수는 value와 다음 index의 value를 같이 활용한다. 

바로 

reduce

 

mdn 부터보겠다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

 

Array.prototype.reduce() - JavaScript | MDN

reduce() 메서드는 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.

developer.mozilla.org

기본 컨셉은 이름과 마찬가지로 '누적'을 하는 함수다. 

arr.reduce(callback[, initialValue])

형태는 이처럼 callback을 받는 함수이며 초기값을 설정할 수 있다.

 

 

예를 들어 배열에 있는 숫자의 총합을 구하라고 했을 때 

let inputVal = [6, 3, 7, 5, 9, 1, 4, 2, 8];
let returnVal = 0;

inputVal.map(value => {
    return returnVal += value;
})
console.log(returnVal);

이런 식으로 반복하여 구할 수가 있다 

reduce를 쓴다면

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

let returnVal = inputVal.reduce((prev, curr) => {
    return prev + curr;
}, 0)
console.log(returnVal);

이렇게 쓸 수 있다. 

(왠지 그리 좋아 보이지가 않는다)

 

어쨌든 reduce의 특이한 점은 2개의 값을 반복적으로 컨트롤한다는 건데 

배열에 2개의 값을 컨트롤한다고 하니 버블 소팅이 생각나 한번 해봤다.

let inputVal = [6, 3, 7, 5, 9, 1, 4, 2, 8];
let returnVal = [];

const bubbleSort = (target) => {
    let againFg = false;
    returnVal = [];
    const result = target.reduce((prev, curr) => {
        if (prev > curr) {
            returnVal.push(curr);
            againFg = true;
            return prev;
        } else {
            returnVal.push(prev);
            return curr;
        }
    });
    returnVal.push(result);
    againFg ? bubbleSort(returnVal) : null;
}

bubbleSort(inputVal);

(뭔가 쓸수록 가독성이 더 안 좋은 거 같다)

 

뭔가 좋은 점을 활용한 예제를 보여주고 싶은데 자꾸 더 안 좋아지는 거 같아

mdn에 좋은 예제가 있어 가져왔다.

Promise를 순차적으로 실행하는 예제인데 reduce의 적절한 활용법 같다.

(근데 아마 난 Promise.all을 쓰지 않을까 싶다)

/**
 * Runs promises from array of functions that can return promises
 * in chained manner
 *
 * @param {array} arr - promise arr
 * @return {Object} promise object
 */
function runPromiseInSequence(arr, input) {
  return arr.reduce(
    (promiseChain, currentFunction) => promiseChain.then(currentFunction),
    Promise.resolve(input)
  );
}

// promise function 1
function p1(a) {
  return new Promise((resolve, reject) => {
    resolve(a * 5);
  });
}

// promise function 2
function p2(a) {
  return new Promise((resolve, reject) => {
    resolve(a * 2);
  });
}

// function 3  - will be wrapped in a resolved promise by .then()
function f3(a) {
 return a * 3;
}

// promise function 4
function p4(a) {
  return new Promise((resolve, reject) => {
    resolve(a * 4);
  });
}

const promiseArr = [p1, p2, f3, p4];
runPromiseInSequence(promiseArr, 10)
  .then(console.log);   // 1200

일단 이런 게 있다고 소개를 했고,

사실 신기함에 이렇게 글을 쓰지만

아무래도 손이 익숙한 대로 개발하다 보니 

과연 쓸 일이 발생할까 모르겠다.

하지만 코딩은 계속 시도하고 써봐야

손에 익어서 쓰게 되더라.

적합한 상황이 있을 때 활용할 수 있도록 해봐야겠다.

 

이 포스팅은 보는 사람들이 

나보다 , mdn보다 더 적절한 곳에 사용했으면 한다. 

 

반응형