[JS] ๐ 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}`);
});
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