range / 느긋한 range + take

KHW·2021년 8월 11일
0

Javascript 지식쌓기

목록 보기
71/95

range / 느긋한 range

const reduce = (f, acc, iter) => {
  if (!iter) {
    iter = acc[Symbol.iterator]();
    acc = iter.next().value;
  }
  for (const a of iter) {
    acc = f(acc, a);
  }
  return acc;
};

const range = (l) => {
  let i = -1;
  let res = [];
  while (++i < l) {
    res.push(i);
  }
  return res;
};

console.log(reduce((a, b) => a + b, range(4)));

const L = {};
L.range = function* (l) {
  let i = -1;
  while (++i < l) {
    yield i;
  }
};

let list = L.range(4);
console.log(reduce((a, b) => a + b, list));

둘다 6의 결과가 출력된다.

두 차이는 ?

const reduce = (f, acc, iter) => {
  if (!iter) {
    iter = acc[Symbol.iterator]();
    acc = iter.next().value;
  }
  for (const a of iter) {
    acc = f(acc, a);
  }
  return acc;
};

const range = (l) => {
  let i = -1;
  let res = [];
  while (++i < l) {
    console.log(i, "range");
    res.push(i);
  }
  return res;
};

range(4);

const L = {};
L.range = function* (l) {
  let i = -1;
  while (++i < l) {
    console.log(i, "L-range");
    yield i;
  }
};

let list = L.range(4);

둘다 range(4)와 L.range(4)를 진행 했음에도
range(4)의 콘솔만 출력이 된다.
즉, L.range에서 이터레이터가 제너레이터를 하나씩 순회하기 전까지는 해당 내용이 출력되지않는다.

차이의 결과는

효율성에서 전부 만들고 진행하는 range와 다르게
어떤 이터레이터 진행이 될때 처리하는 L.range가 더 효율적이다.

take 함수

원하는 크기만큼만 출력해주는 함수

const take = (l, iter) => {
  let res = [];
  for (const a of iter) {
    res.push(a);
    if (res.length == l) return res;
  }
  return res;
};
console.log(take(5, range(100000)));
console.log(take(5, L.range(100000)));

해당 값을 100000에서 Infinity로 바꾸면 range는 계속 돌면서 제대로 결과를 못만들지만 L.range는 문제없다.

3가지의 결과 출력방법

console.log(take(5, range(10000)));
go(range(10000), take(5), console.log);
go(range(10000), (result) => take(5, result), console.log);

const reduce = (f, acc, iter) => {
  if (!iter) {
    iter = acc[Symbol.iterator]();
    acc = iter.next().value;
  }
  for (const a of iter) {
    acc = f(acc, a);
  }
  return acc;
};

const go = (...list) => reduce((a, f) => f(a), list);

const curry = (f) => (a, ..._) =>
  _.length ? f(a, ..._) : (..._) => f(a, ..._);

const range = (l) => {
  let i = -1;
  let res = [];
  while (++i < l) {
    res.push(i);
  }
  return res;
};

range(4);

const L = {};
L.range = function* (l) {
  let i = -1;
  while (++i < l) {
    yield i;
  }
};

const take = curry((l, iter) => {
  let res = [];
  for (const a of iter) {
    res.push(a);
    if (res.length == l) return res;
  }
  return res;
});

console.log(take(5, range(10000)));				//1)
go(range(10000), (result) => take(5, result), console.log);		//2)
go(range(10000), take(5), console.log);				//3)

1) go curry 사용하지 않음
2) go curry를 사용
3) go curry를 사용해서 같은 매개변수를 처리함

profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자

0개의 댓글