Skip to content

Instantly share code, notes, and snippets.

@kpuputti
Last active December 17, 2015 22:49
Show Gist options
  • Save kpuputti/5684447 to your computer and use it in GitHub Desktop.
Save kpuputti/5684447 to your computer and use it in GitHub Desktop.

lazy.js

Like Underscore (or Lo-Dash), but lazier.

http://dtao.github.io/lazy.js/

npm install lazy.js

No external dependencies

Problem with Underscore

Say you have a large collection of data.

You want to make several transformations on it.

And you only take e.g. the top 5 items from it.

Example:

_.chain(data)                 // collection of n items
  .map(transformation1)       // another collection of n items
  .map(transformation2)       // yet another collection of n items
  .map(transformation3)       // and yet another collection of n items
  .filter(onlySomeOfThatShit) // another collection of m (<= n) items
  .pluck('prop')              // another collection of m items
  .take(5)                    // final collection of 5 items
  .value()

Same with lazy.js:

Lazy(data)
  .map(transformation1)
  .map(transformation2)
  .map(transformation3)
  .filter(onlySomeOfThatShit)
  .pluck('prop')
  .take(5)
  .toArray()  // if you wish

Here, every call creates a new Lazy.Sequence object with an each method.

  • No iteration takes place until you call each
  • No itermediate arrays are created
  • Operations are just combined into one sequence

Gimme infinity!

Mmkay, now we're going to the territory of streams and FRP.

Like Python generators or Scala streams:

var shitHackerNewsSays = Lazy.generate(function () {
  return {
    title: 'New JS framework!!1',
    comments: ['shit', 'shit', 'shit']
  };
});

shitHackerNewsSays
  .pluck('comments')
  .flatten()
  .take(100)
  .toArray()  // ['shit', 'shit', 'shit', 'shit', ...]

Async iteration

Ok, bad example:

Laxy.range(1000)
  .async(100)  // 100ms interval between elements
  .map(function (n) {
    return 'n: ' + n;
  })
  .take(10)
  .each(function (s) {
    console.log(s);
  });

DOM extension

DOM events as a sequence.

Include separate lazy.dom.js

var mouseMoveStream = Lazy.events(document.body, 'mousemove');

function toMouseCoordinates(event) {
  return {
    x: event.screenX,
    y: event.screenY
  };
}

var output = document.querySelector('.output');

mouseMoveStream
  .map(toMouseCoordinates)  // no throttle, debounce etc. :(
  .each(function (coords) {
    output.textContent = coords.x + ', ' + coords.y;
  });

Ok, you should probably be using a proper FRP lib already at this point.

String processing

From the docs:

var firstFiveLines = Lazy(longText).split('\n').take(5);

var firstFiveWords = Lazy(longText).match(/[a-z0-9]/i).take(5);

Wrapping Node streams

Lazy(stream)
  .take(5) // 5 first chunks of data
  .each(function () { ... });

Lazy.makeHttpRequest('http://www.futurice.com')
  .lines()  // split the chunks into lines lazily
  .drop(10)
  .take(3) // ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment