명령형 프로그래밍 → 함수형 프로그래밍(이터러블) 로의 변환을 다룸limit과 리스트 list를 인자로 전달받아서 list의 수 중 홀수를 제곱한 후 limit개만 더하는 함수 작성function f1(limit, list) {
let summed = 0; // 더한 값을 저장할 변수
// 리스트의 각 요소를 순회 (for-of 문을 사용)
for (const a of list) {
if (a % 2) { // a가 홀수인지 확인 (a % 2가 참이면 홀수)
const b = a * a;
summed += b; // 홀수이면 제곱해서 summed에 더함
// limit를 1 감소시키고, 감소된 값이 0이면 반복문 종료
if (--limit == 0) break;
}
}
console.log(summed); // 최종 더한 값을 출력
}
f1(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); // 9
--limit : limit를 1씩 감소시키는 표현임if (--limit == 0)는 limit 값을 1 감소시킨 후, 그 값이 0이 되면 break를 통해 반복문을 종료시키는 표현function f1(limit, list) {
let summed = 0;
for (const a of L.filter(a => a % 2, list)) {
// if (a % 2) {
const b = a * a;
summed += b;
if (--limit == 0) break;
}
}
console.log(summed);
}
function f1(limit, list) {
let summed = 0;
for (const a of L.map(a => a * a, L.filter(a => a % 2, list))) {
// const b = a * a;
summed += a;
if (--limit == 0) break;
}
}
console.log(summed);
}
L.map(a => a * a, 대상리스트): 대상리스트를 순회하며 모든 값을 제곱함function f1(limit, list) {
let summed = 0;
for (const a of L.take(limit, L.map(a => a * a, L.filter(a => a % 2, list)))) {
summed += a;
// if (--limit == 0) break;
}
}
console.log(summed);
}
L.take(limit, 대상리스트) : 대상리스트에서 limit개만큼만 꺼내줌function f1(limit, list) {
console.log(
_.reduce((summed, a) => summed + a,
0,
L.take(limit,
L.map(a => a * a,
L.filter(a => a % 2, list)))));
}
// 또는, (summed, a) => summed + a 이 함수를 꺼내서 더 단순하게 적기
const add = (a, b) => a + b;
function f1(limit, list) {
console.log( // 5. 출력함
_.reduce(add, // 4. add 함수로 더한 것을
L.take(limit, // 3. limit개만 뽑은 후,
L.map(a => a * a, // 2. 모든 값들을 제곱하고,
L.filter(a => a % 2, list))))); // 1. list에서 홀수만 걸러낸 후,
}
reduce : 어떤 이터러블 (여기에서는 리스트)을 하나의 값으로 축약이나 합산하는 것
_.go 함수로 순서까지 뒤집어서 가독성 올리기
const add = (a, b) => a + b;
function f1(limit, list) {
_.go(
list,
L.filter(a => a % 2),
L.map(a => a * a),
L.take(limit),
_.reduce(add),
console.log);
}
// 1. 0부터 end까지의 수를 출력하기
function f3(end) {
let i = 0;
while (i < end) {
console.log(i);
++i;
}
}
f3(10);
// 2. 0부터 end까지의 홀수를 전부 출력하기
// (i % 2)를 써서 판별할 수도 있지만, 아래와 같은 방식이 더 영리함
function f3(end) {
let i = 1;
while (i < end) {
console.log(i);
i += 2;
}
}
f3(10);
// 1. 0부터 end까지의 수를 출력하기
function f3(end) {
_.each(console.log, L.range(end));
}
f3(10);
each 로 순회, range로 범위 설정// 2. 0부터 end까지의 홀수를 전부 출력하기
// (i % 2)를 써서 판별할 수도 있지만, 아래와 같은 방식이 더 영리함
function f3(end) {
_.each(console.log, L.range(1, end, 2));
}
f3(10);
_.는 즉시평가되도록 하고자 할 때, L.는 지연적으로 평가되고자 할 때 메소드 앞에 붙여줌// ver 1
_.go(
L.range(1, 6), // 최종 출력에 필요없는 배열들은 L로 설정해서
L.map(L.range), // 굳이 불필요한 배열은 생성하지 않음
L.map(L.map( => '*')),
L.map(_.reduce((a, b) => `${a}${b}`)),
_.reduce((a, b) => `${a}\n${b}`),
console.log);
// ver 1-1: (a, b) => `${a}${b}` 부분 함수로 정의해서 빼기
const join = sep => _.reduce((a, b) => `${a}${sep}${b}`);
_.go(
L.range(1, 6),
L.map(L.range),
L.map(L.map( => '*')),
L.map(join('')),
join('\n')),
console.log);
// ver 2
_.go(
L.range(1, 6),
L.map(s => _.go(
L.range(s),
L.map( => '*'),
_.reduce((a, b) => `${a}${b}`)
)),
_.reduce((a, b) => `${a}\n${b}`),
console.log);
const join = sep => _.reduce((a, b) => `${a}${sep}${b}`);
_.go(
_.range(2, 10),
_.map(a => _.go(
_.range(1, 10),
_.map(b=> `${a}x${b}=${a*b}`),
join('\n')
)),
join('\n\n'),
console.log);
reduce 남용하지 않기// users 데이터의 나이를 합산하는 코드:
const users = [
{ name: 'AA', age: 35 },
{ name: 'BB', age: 26 },
{ name: 'CC', age: 28 },
{ name: 'DD', age: 34 },
{ name: 'EE', age: 23 },
];
// reduce에서, input된 두개의 값의 타입을 통일하면 계산이 더 단순해지므로 권장됨
// ver1: 통일 X
console.log(
_.reduce((total, u) => total + u.age, 0, users));
// ver2: 통일 O
console.log(
_.reduce((a, b) => a + b,
L.map(u => u.age, users)));
// ver2 함수로 대체
const add = (a, b) => a + b;
console.log(
_.reduce(add, L.map(u => u.age, users)));
// users 데이터의 나이를 합산하는 코드:
const users = [
{ name: 'AA', age: 35 },
{ name: 'BB', age: 26 },
{ name: 'CC', age: 28 },
{ name: 'DD', age: 34 },
{ name: 'EE', age: 23 },
];
// problematic code: reduce 하나에 복잡한 함수를 씀
console.log(
_.reduce((total, u) => u.age >= 30 ? total: total + u.age,
0,
users)));
// updated ver
console.log(
_.reduce(add,
_.map(u => u.age,
_.filter(u => u.age < 30, users))));
const obj1 = {
a : 1,
b : undefined,
c: 'CC',
d: 'DD'
}
// 명령형 코드
function query1(obj) {
let res = '';
for (const k in obj) { // k는 key(a, b, c, d)
const v = obj[k]; // v는 value/
if (v === undefined) continue;
if (res != '') res += ' | ';
res += k + ' = ' + v;
}
}
console.log(query1(obj1))
// 함수형 코드
function query2(obj) {
return Object
.entries(obj)
.reduce((query, [k, v], i) => {
if (v === undefined) return query;
return query + (i > 0 ? '&' : '') + k + '=' + v;
}, '');
}
console.log(query2(obj1))