이터러블 프로그래밍 - ChoDragon9/posts GitHub Wiki
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/function*
재귀 함수
range
function range(end, start=0, step=1) {
if (start > end - 1) {
return []
}
return [start, ...range(end, start+step, step)]
}
range(0) // []
range(3) // [0, 1, 2]
map
function map(fn, [head, ...tail]) {
if (head === undefined) {
return []
}
return [fn(head), ...map(fn, tail)]
}
map(v => v * 10, [0, 1, 2]) // [0, 10, 20]
지연리스트 재귀 함수
range
function* range(end, start=0, step=1) {
if (start > end - 1) {
return
}
yield start
yield* range(end, start+step, step)
}
console.log(...range(4)) // 0 1 2 3
map
function* map(fn, list) {
const {value, done} = list.next()
if (done) return
yield fn(value)
yield* map(fn, list)
}
console.log(
...map(v=>v*10, range(3))
) // 0 10 20 30
filter
function* filter(fn, list) {
const {value, done} = list.next()
if (done) return
if (fn(value)) yield value
yield* filter(fn, list)
}
console.log(
...filter(v=>v>3, range(5))
) // 4 5
지연 함수의 종결 함수
collect
const collect = list => [...list]
reduce
function* reduceLazy(fn, list, acc) {
const {value, done} = list.next()
if (done) {
yield acc
return
}
yield* reduceLazy(fn, list, fn(acc, value))
}
const reduce = (fn, list, acc = []) => {
const [result] = collect(reduceLazy(fn, list, acc))
return result
}
console.log(
reduce(
(acc, v)=> acc+v,
range(4),
0
)
)
take
function* takeLazy(end, list, start=1) {
if (start > end) return
const {value} = list.next()
yield value
yield* takeLazy(end, list, start+1)
}
const take = (end, list, start=1) => {
return collect(takeLazy(end, list, start))
}
console.log(
take(2, range(4))
) // [0, 1]