Language/JavaScript

[JS] ๐Ÿ“š reduce ๊ณ ์ฐจํ•จ์ˆ˜ - ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์„ค๋ช…

์ธํŒŒ_ 2021. 9. 28. 21:50

reduce()

โ€‹Array์—๋Š” map()์ด๋‚˜ filter()๋‚˜ join() ๊ฐ™์€ ๋ฉ”์†Œ๋“œ๋“ค์ด ์žˆ๋‹ค. ์‚ฌ์‹ค ์œ„์˜ ๊ธฐ๋Šฅ์€ ๋ชจ๋‘ reduce๋กœ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค. for in, for of, forEach ๋ฅผ ๋ชฐ๋ผ๋„ ์ƒ for๋ฌธ์œผ๋กœ ๋ชจ๋‘ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋“ฏ์ด ๋ง์ด๋‹ค.

ํ•œ๋งˆ๋””๋กœ reduce๋Š” Array๋ฉ”์†Œ๋“œ๋“ค์˜ ์•„๋ฒ„์ง€๋ผ๊ณ ๋„ ๋ถˆ๋ฆฌ์šธ์ˆ˜๋„ ์žˆ๋‹ค. ๋˜ํ•œ initialValue์— ๋ฐฐ์—ด์ด๋‚˜ ๊ฐ์ฒด๋ฅผ ์ฃผ๋ฉด ์ „์—ญ์œผ๋กœ ๊ฐ์ฒด๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“œ๋Š” ๋“ฏํ•œ ํšจ๊ณผ๋ฅผ ๋‚ผ ์ˆ˜ ๋„ ์žˆ๋‹ค.

 

reduce ๊ณ ์ฐจํ•จ์ˆ˜

- ๋ฐฐ์—ด์˜ ์™ผ์ชฝ๋ถ€ํ„ฐ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ ํ›„ ๋ˆ„์‚ฐํ•จ

 

๋ฐฐ์—ด.reduce( function(acc, cur, index, arr) {

} [, initialValue] )

  • ๋ˆ„์‚ฐ๊ธฐaccumulator (acc)
  • ํ˜„์žฌ ๊ฐ’ (cur)
  • ํ˜„์žฌ ์ธ๋ฑ์Šค (idx)
  • ์›๋ณธ ๋ฐฐ์—ด (src)
  • initialValue(optional : ์‚ฌ์šฉํ•ด๋„ ๋˜๊ณ  ์•ˆํ•ด๋„ ๋˜๊ณ ) : callback์˜ ์ตœ์ดˆ ํ˜ธ์ถœ์—์„œ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜์— ์ œ๊ณตํ•˜๋Š” ๊ฐ’.
    ์ดˆ๊ธฐ๊ฐ’์„ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋นˆ ๋ฐฐ์—ด์—์„œ ์ดˆ๊ธฐ๊ฐ’ ์—†์ด reduce()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
const numbers = [1, 2, 3, 4]; 

// ์ผ๋ฐ˜ for๋ฌธ
let result = 0; 
for (i = 0; i < numbers.length; i++) { 
   result += numbers[i]; 
}
console.log(result); // 20;

//-----------------------------------------

const result = numbers.reduce((number1, number2) => number1 + number2); 
/* 
  1,2 => 3  ๋ฐฐ์—ด๊ฐ’ 1๋ฒˆ์งธ, 2๋ฒˆ์งธ ๋ถ€ํ„ฐ ์‹œ์ž‘
  3,3 => 6
  6,4 => 10
*/
console.log(result); // 10;

//-------------------------------------------

const result = numbers.reduce((number1, number2) => number1 + number2, 10); 
/* 
  10,1 => 11   initialValue๊ฐ’, ๋ฐฐ์—ด๊ฐ’ 1๋ฒˆ์งธ ๋ถ€ํ„ฐ ์‹œ์ž‘
  11,2 => 13
  13,3 => 16
  16,4 => 20
*/
console.log(result); // 20;

์ฃผ์–ด์ง„ ๊ฐ’๋“ค์„ reduce๋ฅผ ํ†ตํ•ด ํ•ฉ์‚ฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๋ฌผ๋ก  for๋ฌธ์„ ์‚ฌ์šฉํ•ด์„œ๋„ ์ด์™€ ๊ฐ™์€ ์ž‘์—…์„ ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ ๊ถŒ์žฅํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.

map, filter, reduce์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ˆœ์ฐจ์ ์œผ๋กœ ๊ฐ’์„ ์ ‘๊ทผํ•œ๋‹ค๋ผ๋Š” ๊ฐœ๋…์„ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— for๋ฌธ์„ ์‚ฌ์šฉํ•  ๋•Œ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๋ฐ˜๋ณต๋ฌธ์„ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

โ€‹

์ด๋ฐ–์˜ ๋‹ค๋ฅธ ์‚ฐ์ˆ  ๊ฒฐ๊ณผ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

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

const sumByPlus = numbers.reduce((number1, number2) => number1 + number2);
const sumByMinus = numbers.reduce((number1, number2) => number1 - number2);
const sumByMulti = numbers.reduce((number1, number2) => number1 * number2);

console.log(sumByPlus); // 10
console.log(sumByMinus); // -8
console.log(sumByMulti); // 24

reduce์˜ initValue ์†์„ฑ

 

initValue๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ

var res = [0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
    console.log(`accumulator : ${accumulator}`);
    console.log(`currentValue : ${currentValue}`);
    console.log(`currentIndex : ${currentIndex}`);
    console.log("                              ");
    return accumulator + currentValue;
});

console.log("res:", res); //10

initialValue๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฉด, reduce()๋Š” ์ธ๋ฑ์Šค 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์ฒซ ๋ฒˆ์งธ ์ธ๋ฑ์Šค๋Š” ๊ฑด๋„ˆ ๋›ด๋‹ค.

reduce()ํ•จ์ˆ˜ ํ˜ธ์ถœ์‹œ initialValue ๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ
- accumulator ๋Š” ๋ฐฐ์—ด์˜ ์ฒซ๋ฒˆ์งธ ๊ฐ’
- currentValue ๋Š” ๋ฐฐ์—ด์˜ ๋‘๋ฒˆ์งธ ๊ฐ’

์ฝœ๋ฐฑ์€ 4๋ฒˆ ํ˜ธ์ถœ๋œ๋‹ค. ๊ฐ ํ˜ธ์ถœ์˜ ์ธ์ˆ˜์™€ ๋ฐ˜ํ™˜๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

callback accumulator currentValue currentIndex array ๋ฐ˜ํ™˜ ๊ฐ’
1๋ฒˆ์งธ ํ˜ธ์ถœ 0 1 1 [0, 1, 2, 3, 4] 1
2๋ฒˆ์งธ ํ˜ธ์ถœ 1 2 2 [0, 1, 2, 3, 4] 3
3๋ฒˆ์งธ ํ˜ธ์ถœ 3 3 3 [0, 1, 2, 3, 4] 6
4๋ฒˆ์งธ ํ˜ธ์ถœ 6 4 4 [0, 1, 2, 3, 4] 10

reduce()๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์œผ๋กœ๋Š” ๋งˆ์ง€๋ง‰ ์ฝœ๋ฐฑ ํ˜ธ์ถœ์˜ ๋ฐ˜ํ™˜๊ฐ’(10)์„ ์‚ฌ์šฉํ•œ๋‹ค

โ€‹

initValue๊ฐ’์ด ์žˆ๋Š” ๊ฒฝ์šฐ

var res = [0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
    console.log(`accumulator : ${accumulator}`);
    console.log(`currentValue : ${currentValue}`);
    console.log(`currentIndex : ${currentIndex}`);
    console.log("                              ");
    return accumulator + currentValue;
}, 10); // ๋ˆ„์‚ฐ๊ธฐ ์ดˆ๊นƒ๊ฐ’ 10์„ ์ฃผ์—ˆ๋‹ค.

console.log("res:", res); //20

โ€‹initialValue๋ฅผ ์ œ๊ณตํ•˜๋ฉด ์ธ๋ฑ์Šค 0์—์„œ ์‹œ์ž‘ํ•œ๋‹ค. 

reduce()ํ•จ์ˆ˜ ํ˜ธ์ถœ์‹œ initialValue ๊ฐ’์ด ์žˆ๋Š” ๊ฒฝ์šฐ
- accumulator ๋Š” initialValue
- currentValue ๋Š” ๋ฐฐ์—ด์˜ ์ฒซ๋ฒˆ์งธ ๊ฐ’
callback accumulator currentValue currentIndex array ๋ฐ˜ํ™˜ ๊ฐ’
1๋ฒˆ์งธ ํ˜ธ์ถœ 10 0 0 [0, 1, 2, 3, 4] 10
2๋ฒˆ์งธ ํ˜ธ์ถœ 10 1 1 [0, 1, 2, 3, 4] 11
3๋ฒˆ์งธ ํ˜ธ์ถœ 11 2 2 [0, 1, 2, 3, 4] 13
4๋ฒˆ์งธ ํ˜ธ์ถœ 13 3 3 [0, 1, 2, 3, 4] 16
5๋ฒˆ์งธ ํ˜ธ์ถœ 16 4 4 [0, 1, 2, 3, 4] 20

reduce ํ™œ์šฉ ์‹ค์ „ ์˜ˆ์ œ

โ€‹

๊ฐ์ฒด ๋ฐฐ์—ด์—์„œ์˜ ๊ฐ’ ํ•ฉ์‚ฐ

๊ฐ์ฒด๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฐฐ์—ด์— ๋“ค์–ด ์žˆ๋Š” ๊ฐ’์„ ํ•ฉ์‚ฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ˜๋“œ์‹œ initialValue์ดˆ๊ธฐ๊ฐ’์„ ์ฃผ์–ด ๊ฐ ํ•ญ๋ชฉ์ด ์—ฌ๋Ÿฌ๋ถ„์˜ ํ•จ์ˆ˜๋ฅผ ๊ฑฐ์น˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.

var initialValue = 0;
var list = [
    { x : 1 },
    { x : 2 },
    { x : 3 }
];
var sum = list.reduce(function (accumulator, currentValue) {
    return accumulator + currentValue.x;
}, initialValue)

console.log(sum) // logs 6

 

์ค‘์ฒฉ ๋ฐฐ์—ด ํŽผ์น˜๊ธฐ

var arr = [
    [0, 1],
    [2, 3],
    [4, 5]
]
var flattened = arr.reduce(function(accumulator, currentValue) {
        return accumulator.concat(currentValue);
     // return acc = [...acc, ...cur];
    }
,[]);
console.log(flattened); //[0, 1, 2, 3, 4, 5]

 

์†์„ฑ์œผ๋กœ ๊ฐ์ฒด ๋ถ„๋ฅ˜ํ•˜๊ธฐ

age๊ฐ€, ๋‚˜์ด๊ฐ€ ๋ช‡์ด๋ƒ ์— ๋”ฐ๋ผ ๊ฐ์ฒด๋ฅผ ์žฌ์ •๋ ฌ ์ •๋ฆฌํ•ด์„œ ๋ฌถ์–ด์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ”๋“œ.

var peoples = [
    {
        name : 'Alice',
        age : 21
    },
    {
        name : 'Max',
        age : 20
    },
    {
        name : 'Jane',
        age : 20
    }

];

function groupBy(objectArray, property){
    return objectArray.reduce(function (accumulator, currentObj) {
        var key = currentObj[property];
        console.log(`key : ${key}`);
        if (!accumulator[key]) {
            accumulator[key] = [];
        }
        accumulator[key].push(currentObj);
        return accumulator;
    }, {}); // ๋ˆ„์‚ฐ๊ธฐ๋ฅผ ์‚ฐ์ˆ ์— ์“ฐ์ง€์•Š๊ณ  ๋นˆ ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์„ ์ค˜์„œ ์—ฌ๊ธฐ์—๋‹ค ๋‹ด๋Š” ์šฉ๋„๋กœ๋„ ์“ด๋‹ค.
};

var groupedPeople = groupBy(peoples, 'age');
console.log(`groupedPeople : ${JSON.stringify(groupedPeople)}`);
/*
"age" ์†์„ฑ์œผ๋กœ ๊ฐ์ฒด ๋ถ„๋ฅ˜ (๋‚˜์ด ๋ณ„)
groupedPeople : {
	"20":[{"name":"Max","age":20},{"name":"Jane","age":20}],
    "21":[{"name":"Alice","age":21}]
}
*/

 

๋ฐฐ์—ด์˜ ์ค‘๋ณต ํ•ญ๋ชฉ ์ œ๊ฑฐ

์‚ฌ์‹ค ์ด๋ ‡๊ฒŒ ํ•˜๋Š”๊ฒƒ๋ณด๋‹ค ์ค‘๋ณต์ด ์—†๋‹ค๋Š” set ์ž๋ฃŒํ˜•์„ ์ด์šฉํ•ด ๊ทธ๋ƒฅ new Set(arr)ํ•˜๋ฉด ๋์ด๊ธดํ•˜๋‹ค. reduce๋ฅผ ์ด๋Ÿฐ์‹์œผ๋กœ ํ™œ์šฉํ• ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฐœ๋…์ •๋„๋Š” ์•Œ์ž

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

let result = arr.sort().reduce((accumulator, currentValue) => {
    const length = accumulator.length
    if (length === 0 || accumulator[length - 1] !== currentValue) {
        accumulator.push(currentValue);
    }
    return accumulator;
}, []);
console.log(result); 
//[1,2,3,4,5]

โ€‹

filter ๋ฅผ reduce ๋กœ ๊ตฌํ˜„

[ 2, 4, 5, 6, 8 ].filter(val => val % 2 === 0) // [2, 4, 6, 8]

[ 2, 4, 5, 6, 8 ].reduce((acc, val) => {
    if(val % 2 === 0)
        acc.push(val)
    return acc;
}, []); // [2, 4, 6, 8]

โ€‹

filter + map ์กฐํ•ฉ์„ reduce ํ•˜๋‚˜๋กœ ๊ตฌํ˜„

[ 2, 4, 5, 6, 8 ]
    .filter(val => val % 2 === 0)
    .map(val => val * 10); // [20, 40, 60, 80]

// ๋ฃจํ”„ ํ•œ๋ฒˆ์— filter, map ์™„๋ฃŒ.
[ 2, 4, 5, 6, 8 ].reduce((acc, val) => {
    if(val%2 === 0) {
        acc.push(val * 10)
    }
    return acc;
}, []);

โ€‹

2์ฐจ์› ๋ฐฐ์—ด ํ’€๊ธฐ

[ [9,2], [8,7] ].reduce((acc, val) => [ ...acc, ...val ], []) // [9, 2, 8, 7]

โ€‹

ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ•˜๊ธฐ

function runPromiseInSequence(arr, input){
    return arr.reduce(function(accumulator, currentFunction){
        console.log(`accumulator : ${accumulator}`);
        console.log(`currentFunction : ${currentFunction}`);
        console.log(`                                    `);
        return accumulator.then(currentFunction); 
        // accumulator๊ฐ€ resolveํ•ด์„œ input๊ฐ’์„ ์ค˜์„œ then์—์„œ input์„ ์ธ์ž๋ผ ๋ฐ›์•„์„œ ํ•จ์ˆ˜ ์‹คํ–‰ํ•˜๋Š” ๊ฒฉ
    }, Promise.resolve(input));
};

function promise1(value){
    return new Promise(function(resolve, reject){
        console.log(`promise1 -value : ${value}`)
        resolve(value * 5);
    });
};

function promise2(value){
    return new Promise(function(resolve, reject){
        console.log(`promise2 -value : ${value}`)
        resolve(value * 2);
    });
};
  
function function3(value){
    return value * 3;
};

function promise4(value){
    return new Promise(function(resolve, reject){
        console.log(`promise4 -value : ${value}`)
        resolve(value * 4);
    });
};

const promiseArr = [promise1, promise2, function3, promise4, ]
runPromiseInSequence(promiseArr, 10)
.then(function(value){
    console.log(`result value : ${value}`);
});

reduce()


reduceRight ๊ณ ์ฐจํ•จ์ˆ˜

  • reduce ๋Š” ์™ผ์ชฝ ์›์†Œ๋ถ€ํ„ฐ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰
  • reduceRight ๋Š” ์˜ค๋ฅธ์ชฝ ์›์†Œ๋ถ€ํ„ฐ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰
var arr = ["๊ฒฝ๊ธฐ๋„", "์•ˆ์–‘์‹œ", "๋งŒ์•ˆ๊ตฌ"];

var result = arr.reduceRight((acc, element) => acc + " " + element);

console.log(result); //  ๋งŒ์•ˆ๊ตฌ ์•ˆ์–‘์‹œ ๊ฒฝ๊ธฐ๋„
console.log(typeof result); // string

์œ„ ์ฝ”๋“œ๋Š” ๋งˆ์น˜ Array.join(' ') ๊ฐ™์ง€ ์•Š์€๊ฐ€?

์ด์ฒ˜๋Ÿผ reduce๋Š” ๋ชจ๋“ ๊ฑธ ๊ตฌํ˜„ํ• ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋งŒ๋Šฅ ๋„๊ตฌ์ด๋‹ค.


# ์ฐธ๊ณ ์ž๋ฃŒ

https://www.zerocho.com/category/JavaScript/post/5acafb05f24445001b8d796d

https://steemit.com/javascript/@rouka/reduce

https://bbaktaeho-95.tistory.com/35