🔧 reduce에 담기기전 list의 상태는 배열이다
const add = (a,b) => a+b;
const range = l => {
let i = -1;
let res = [];
while(++i<l){
log(i,'range');
res.push(i);
}
return res;
};
log(range(5));
// [0,1,2,3,4]
var list = range(4);
log(list); // [0,1,2,3]
log(reduce(add ,list)) // 6
🔧 while안 log(i,'range'); 결과
0"range"
1"range"
2"range"
3"range"
🔧 배열을 만들지 않고 제너레이터를 이용해 생성하고 리턴한다.
const L = {};
L.range = function *(l){
let i = -1;
while(++i<l){
log(i,'L.range');
yield i;
}
};
log(range(5));
// [0,1,2,3,4]
var list = range(4);
log(list); // L.range {}
log(reduce(add ,list)) // 6
🔧 while안 log(i,'L.range'); 결과 실행되지 않는다.
list.next()가 실행되기 전까진 어떠한 코드도 동작하지 않는다.
log(list.next()); 를 한다면
0'L.range' {value:0,done:false}
1'L.range' {value:1,done:false}
...
🔧
function test(name, time, f) {
console.time(name);
while (time--) f();
console.timeEnd(name);
}
test('L.range',10,()=>reduce(add, L.range(100000))); // L.range:257.204833..
test('range',10,()=>reduce(add, range(100000))); // range:489.6808..
🔧 L.range 같이 지연성을 가지는 값을 iterator로 만들게 되면 전혀 다른 take와 같은 함수가 iterator 프로토콜만 따른다면 소통이 가능하다.
take(5, L.range(10000))에서 10000의 array를 만들지 않고 5개의 값만 만들기 떄문에 10000개의 index를 가진 array를 만들어 내는 range(10000) 보다 빠르다.
const take = curry((l, iter))=>{
let res = [];
for(const a of iter){
res.push(a);
if(res.length == l) return res;
}
return res;
};
log(range(100)); // [0,1,2....,99]
log(take(5, L.range(100)); // [0,1,2,3,4]
go(L.range(10000),take(5),log); // [0,1,2,3,4]
🔧
L.map = function *(f, iter) {
for(const a of iter) yield f(a);
};
var it = L.map(a => a+10, [1,2,3]);
log(it.next().value); // 11
🔧 for of문을 while문으로 표현
L.map = function *(f, iter) {
let res = [];
iter = iter[Symbol.iterator]();
let cur;
while(!(cur = iter.next()).done){
const a = cur.value;
res.push(f(a))
}
};
🔧 f(a) true시 반환 즉, 1일때 a%2 는 홀수 즉 나머지가 1인 값을 찾음
L.filter = function *(f, iter) {
for(const a of iter) if(f(a)) yield f(a);
};
L.filter(a=>a % 2, [1,2,3,4]);
log(it.next()); // 1
log(it.next()); // 3
🔧