A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://dtao.github.io/lazy.js/docs/ below:

Lazy.js API Docs - v0.5.1

Lazy.js is a lazy evaluation library for JavaScript.

This has been done before. For examples see:

However, at least at present, Lazy.js is faster (on average) than any of those libraries. It is also more complete, with nearly all of the functionality of Underscore and Lo-Dash.

Finding your way around the code

At the heart of Lazy.js is the Sequence object. You create an initial sequence using Lazy, which can accept an array, object, or string. You can then "chain" together methods from this sequence, creating a new sequence with each call.

Here's an example:

var data = getReallyBigArray();

var statistics = Lazy(data)
  .map(transform)
  .filter(validate)
  .reduce(aggregate);

Sequence is the foundation of other, more specific sequence types.

An ArrayLikeSequence provides indexed access to its elements.

An ObjectLikeSequence consists of key/value pairs.

A StringLikeSequence is like a string (duh): actually, it is an ArrayLikeSequence whose elements happen to be characters.

An AsyncSequence is special: it iterates over its elements asynchronously (so calling each generally begins an asynchronous loop and returns immediately).

For more information

I wrote a blog post that explains a little bit more about Lazy.js, which you can read here.

You can also create an issue on GitHub if you have any issues with the library. I work through them eventually.

@dtao

Lazy Lazy

Wraps an object and returns a Sequence. For null or undefined, simply returns an empty sequence (see Lazy.strict for a stricter implementation).

Signature
function Lazy(source) {  }
function Lazy(source) {
  if (isArray(source)) {
    return new ArrayWrapper(source);

  } else if (typeof source === "string") {
    return new StringWrapper(source);

  } else if (source instanceof Sequence) {
    return source;
  }

  if (Lazy.extensions) {
    var extensions = Lazy.extensions, length = extensions.length, result;
    while (!result && length--) {
      result = extensions[length](source);
    }
    if (result) {
      return result;
    }
  }

  return new ObjectWrapper(source);
}
Name Type(s) Description source Array|Object|string

An array, object, or string to wrap.

returns Sequence

The wrapped lazy object.

Examples
Lazy([1, 2, 4])       
Lazy({ foo: "bar" })  
Lazy("hello, world!") 
Lazy()                
Lazy(null)            
createWrapper Lazy.createWrapper

Defines a wrapper for custom StreamLikeSequences. This is useful if you want a way to handle a stream of events as a sequence, but you can't use Lazy's existing interface (i.e., you're wrapping an object from a library with its own custom events).

This method defines a factory: that is, it produces a function that can be used to wrap objects and return a Sequence. Hopefully the example will make this clear.

Signature
Lazy.createWrapper = function(initializer) {  }
Lazy.createWrapper = function createWrapper(initializer) {
  var ctor = function() {
    this.listeners = [];
  };

  ctor.prototype = Object.create(StreamLikeSequence.prototype);

  ctor.prototype.each = function(listener) {
    this.listeners.push(listener);
  };

  ctor.prototype.emit = function(data) {
    var listeners = this.listeners;

    for (var len = listeners.length, i = len - 1; i >= 0; --i) {
      if (listeners[i](data) === false) {
        listeners.splice(i, 1);
      }
    }
  };

  return function() {
    var sequence = new ctor();
    initializer.apply(sequence, arguments);
    return sequence;
  };
}
Name Type(s) Description initializer Function

An initialization function called on objects created by this factory. this will be bound to the created object, which is an instance of StreamLikeSequence. Use emit to generate data for the sequence.

returns Function

A function that creates a new StreamLikeSequence, initializes it using the specified function, and returns it.

Examples
var factory = Lazy.createWrapper(function(eventSource) {
  var sequence = this;

  eventSource.handleEvent(function(data) {
    sequence.emit(data);
  });
});

var eventEmitter = {
  triggerEvent: function(data) {
    eventEmitter.eventHandler(data);
  },
  handleEvent: function(handler) {
    eventEmitter.eventHandler = handler;
  },
  eventHandler: function() {}
};

var events = [];

factory(eventEmitter).each(function(e) {
  events.push(e);
});

eventEmitter.triggerEvent('foo');
eventEmitter.triggerEvent('bar');

events 
generate Lazy.generate

Creates a GeneratedSequence using the specified generator function and (optionally) length.

Signature
Lazy.generate = function(generatorFn, length) {  }
Lazy.generate = function generate(generatorFn, length) {
  return new GeneratedSequence(generatorFn, length);
}
Name Type(s) Description generatorFn function(number):*

The function used to generate the sequence. This function accepts an index as a parameter and should return a value for that index in the resulting sequence.

length number?

The length of the sequence, for sequences with a definite length.

returns GeneratedSequence

The generated sequence.

Examples
var randomNumbers = Lazy.generate(Math.random);
var countingNumbers = Lazy.generate(function(i) { return i + 1; }, 5);

randomNumbers          
randomNumbers.length() 
countingNumbers          
countingNumbers.length() 
range Lazy.range

Creates a sequence from a given starting value, up to a specified stopping value, incrementing by a given step. Invalid values for any of these arguments (e.g., a step of 0) result in an empty sequence.

Signature
Lazy.range = function() {  }
Lazy.range = function range() {
  var start = arguments.length > 1 ? arguments[0] : 0,
      stop  = arguments.length > 1 ? arguments[1] : arguments[0],
      step  = arguments.length > 2 && arguments[2];

  if (step === false) {
    step = stop > start ? 1 : -1;
  }

  if (step === 0) {
    return Lazy([]);
  }

  return Lazy.generate(function(i) { return start + (step * i); })
    .take(Math.ceil((stop - start) / step));
}
Name Type(s) Description returns GeneratedSequence

The sequence defined by the given ranges.

Examples
Lazy.range(3)         
Lazy.range(1, 4)      
Lazy.range(2, 10, 2)  
Lazy.range(5, 1, 2)   
Lazy.range(5, 15, -2) 
Lazy.range(3, 10, 3)  
Lazy.range(5, 2)      
Lazy.range(7, 2, -2)  
Lazy.range(3, 5, 0)   
repeat Lazy.repeat

Creates a sequence consisting of the given value repeated a specified number of times.

Signature
Lazy.repeat = function(value, count) {  }
Lazy.repeat = function repeat(value, count) {
  return Lazy.generate(function() { return value; }, count);
}
Name Type(s) Description value *

The value to repeat.

count number?

The number of times the value should be repeated in the sequence. If this argument is omitted, the value will repeat forever.

returns GeneratedSequence

The sequence containing the repeated value.

Examples
Lazy.repeat("hi", 3)          
Lazy.repeat("young")          
Lazy.repeat("young").length() 
Lazy.repeat("young").take(3)  
strict Lazy.strict

Provides a stricter version of Lazy which throws an error when attempting to wrap null, undefined, or numeric or boolean values as a sequence.

Signature
Lazy.strict = function() {  }
Lazy.strict = function strict() {
  function StrictLazy(source) {
    if (source == null) {
      throw new Error("You cannot wrap null or undefined using Lazy.");
    }

    if (typeof source === "number" || typeof source === "boolean") {
      throw new Error("You cannot wrap primitive values using Lazy.");
    }

    return Lazy(source);
  };

  Lazy(Lazy).each(function(property, name) {
    StrictLazy[name] = property;
  });

  return StrictLazy;
}
Name Type(s) Description returns Function

A stricter version of the Lazy helper function.

Examples
var Strict = Lazy.strict();

Strict()                  
Strict(null)              
Strict(true)              
Strict(5)                 
Strict([1, 2, 3])         
Strict({ foo: "bar" })    
Strict("hello, world!")   


Strict.range(3)           
Strict.generate(Date.now) 
Sequence Sequence

The Sequence object provides a unified API encapsulating the notion of zero or more consecutive elements in a collection, stream, etc.

Lazy evaluation

Generally speaking, creating a sequence should not be an expensive operation, and should not iterate over an underlying source or trigger any side effects. This means that chaining together methods that return sequences incurs only the cost of creating the Sequence objects themselves and not the cost of iterating an underlying data source multiple times.

The following code, for example, creates 4 sequences and does nothing with source:

var seq = Lazy(source) 
  .map(func)           
  .filter(pred)        
  .reverse();          

Lazy's convention is to hold off on iterating or otherwise doing anything (aside from creating Sequence objects) until you call each:

seq.each(function(x) { console.log(x); });
Defining custom sequences

Defining your own type of sequence is relatively simple:

  1. Pass a method name and an object containing function overrides to Sequence.define. If the object includes a function called init, this function will be called upon initialization.
  2. The object should include at least either a getIterator method or an each method. The former supports both asynchronous and synchronous iteration, but is slightly more cumbersome to implement. The latter supports synchronous iteration and can be automatically implemented in terms of the former. You can also implement both if you want, e.g. to optimize performance. For more info, see Iterator and AsyncSequence.

As a trivial example, the following code defines a new method, sample, which randomly may or may not include each element from its parent.

Lazy.Sequence.define("sample", {
  each: function(fn) {
    return this.parent.each(function(e) {
      
      if (Math.random() > 0.5) {
        return fn(e);
      }
    });
  }
});

(Of course, the above could also easily have been implemented using #filter instead of creating a custom sequence. But I did say this was a trivial example, to be fair.)

Now it will be possible to create this type of sequence from any parent sequence by calling the method name you specified. In other words, you can now do this:

Lazy(arr).sample();
Lazy(arr).map(func).sample();
Lazy(arr).map(func).filter(pred).sample();

Etc., etc.

define Sequence.define

Create a new constructor function for a type inheriting from Sequence.

Signature
Sequence.define = function(methodName, overrides) {  }
Sequence.define = function define(methodName, overrides) {
  if (!overrides || (!overrides.getIterator && !overrides.each)) {
    throw new Error("A custom sequence must implement *at least* getIterator or each!");
  }

  return defineSequenceType(Sequence, methodName, overrides);
}
Name Type(s) Description methodName string|Array.<string>

The name(s) of the method(s) to be used for constructing the new sequence. The method will be attached to the Sequence prototype so that it can be chained with any other sequence methods, like #map, #filter, etc.

overrides Object

An object containing function overrides for this new sequence type. Must include either getIterator or each (or both). May include an init method as well. For these overrides, this will be the new sequence, and this.parent will be the base sequence from which the new sequence was constructed.

returns Function

A constructor for a new type inheriting from Sequence.

Examples


Lazy.Sequence.define("verbose", {
  init: function(logger) {
    this.logger = logger;
  },

  each: function(fn) {
    var logger = this.logger;
    return this.parent.each(function(e, i) {
      logger(e);
      return fn(e, i);
    });
  }
});

Lazy([1, 2, 3]).verbose(logger).each(Lazy.noop) 
async Sequence#async

Creates a sequence, with the same elements as this one, that will be iterated over asynchronously when calling each.

Signature
Sequence.async = function(interval) {  }
Sequence.async = function async(interval) {
  return new AsyncSequence(this, interval);
}
Name Type(s) Description interval number?

The approximate period, in milliseconds, that should elapse between each element in the resulting sequence. Omitting this argument will result in the fastest possible asynchronous iteration.

returns AsyncSequence

The new asynchronous sequence.

Examples
Lazy([1, 2, 3]).async(100).each(fn) 
chunk Sequence#chunk

Breaks this sequence into chunks (arrays) of a specified length.

Signature
Sequence.chunk = function(size) {  }
Sequence.chunk = function chunk(size) {
  if (size < 1) {
    throw new Error("You must specify a positive chunk size.");
  }

  return new ChunkedSequence(this, size);
}
Name Type(s) Description size number

The size of each chunk.

returns Sequence

The resulting sequence of chunks.

Examples
Lazy([]).chunk(2)        
Lazy([1, 2, 3]).chunk(2) 
Lazy([1, 2, 3]).chunk(1) 
Lazy([1, 2, 3]).chunk(4) 
Lazy([1, 2, 3]).chunk(0) 
compact Sequence#compact

Creates a new sequence with the same elements as this one, except for all falsy values (false, 0, "", null, and undefined).

Signature
Sequence.compact = function() {  }
Sequence.compact = function compact() {
  return this.filter(function(e) { return !!e; });
}
Name Type(s) Description returns Sequence

The new sequence.

Examples
Lazy(["foo", null, "bar", undefined]).compact() 
concat Sequence#concat

Creates a new sequence with all of the elements of this one, plus those of the given array(s).

Signature
Sequence.concat = function(var_args) {  }
Sequence.concat = function concat(var_args) {
  return new ConcatenatedSequence(this, arraySlice.call(arguments, 0));
}
Name Type(s) Description var_args ...*

One or more values (or arrays of values) to use for additional items after this sequence.

returns Sequence

The new sequence.

Examples
var left  = [1, 2, 3];
var right = [4, 5, 6];

Lazy(left).concat(right)             
Lazy(left).concat(Lazy(right))       
Lazy(left).concat(right, [7, 8])     
Lazy(left).concat([4, [5, 6]])       
Lazy(left).concat(Lazy([4, [5, 6]])) 
consecutive Sequence#consecutive

Groups this sequence into consecutive (overlapping) segments of a specified length. If the underlying sequence has fewer elements than the specified length, then this sequence will be empty.

Signature
Sequence.consecutive = function(length) {  }
Sequence.consecutive = function consecutive(count) {
  return new ConsecutiveSequence(this, count);
}
Name Type(s) Description length number

The length of each consecutive segment.

returns Sequence

The resulting sequence of consecutive segments.

Examples
function sum(vals) { return Lazy(vals).sum(); }
var pairs = Lazy([1, 2, 3, 4]).consecutive(2);


pairs.map(sum) 
pairs.map(sum) 

Lazy([]).consecutive(2)        
Lazy([1]).consecutive(2)       
Lazy([1, 2]).consecutive(2)    
Lazy([1, 2, 3]).consecutive(2) 
Lazy([1, 2, 3]).consecutive(0) 
Lazy([1, 2, 3]).consecutive(1) 
contains Sequence#contains

Checks whether the given value is in this sequence.

Signature
Sequence.contains = function(value, equalityFn) {  }
Sequence.contains = function contains(value, equalityFn) {
  return this.indexOf(value, equalityFn) !== -1;
}
Name Type(s) Description value *

The element to search for in the sequence.

equalityFn Function?

An optional equality function, which should take two arguments and return true or false to indicate whether those values are considered equal.

returns boolean

True if the sequence contains the value, false if not.

Examples
var numbers = [5, 10, 15, 20];

Lazy(numbers).contains(15) 
Lazy(numbers).contains(13) 
countBy Sequence#countBy

Creates a new ObjectLikeSequence containing the unique keys of all the elements in this sequence, each paired with the number of elements in this sequence having that key.

Signature
Sequence.countBy = function(keyFn) {  }
Sequence.countBy = function countBy(keyFn) {
  return new CountedSequence(this, keyFn);
}
Name Type(s) Description keyFn Function|string

The function to call on the elements in this sequence to obtain a key by which to count them, or a string representing a parameter to read from all the elements in this sequence.

returns Sequence

The new sequence.

Examples
function oddOrEven(x) {
  return x % 2 === 0 ? 'even' : 'odd';
}

var numbers = [1, 2, 3, 4, 5];

Lazy(numbers).countBy(oddOrEven)            
Lazy(numbers).countBy(oddOrEven).get("odd") 
Lazy(numbers).countBy(oddOrEven).get("foo") 
dropWhile Sequence#dropWhile

aliases: skipWhile

Creates a new sequence comprising the elements from this sequence after those that satisfy some predicate. The sequence starts with the first element that does not match the predicate.

Signature
Sequence.dropWhile = function(predicate) {  }
Sequence.dropWhile = function dropWhile(predicate) {
  return new DropWhileSequence(this, predicate);
}
Name Type(s) Description predicate Function returns Sequence

The new sequence

each Sequence#each

aliases: forEach

Iterates over this sequence and executes a function for every element.

Signature
Sequence.each = function(fn) {  }
Sequence.each = function each(fn) {
  var iterator = this.getIterator(),
      i = -1;

  while (iterator.moveNext()) {
    if (fn(iterator.current(), ++i) === false) {
      return false;
    }
  }

  return true;
}
Name Type(s) Description fn Function

The function to call on each element in the sequence. Return false from the function to end the iteration.

returns boolean

true if the iteration evaluated the entire sequence, or false if iteration was ended early.

Examples
Lazy([1, 2, 3, 4]).each(fn) 
equals Sequence#equals

Compare this to another sequence for equality.

Signature
Sequence.equals = function(other, equalityFn) {  }
Sequence.equals = function equals(other, equalityFn) {
  if (!(other instanceof Sequence)) {
    return false;
  }

  var it  = this.getIterator(),
      oit = other.getIterator(),
      eq  = equalityFn || Lazy.equality;
  while (it.moveNext()) {
    if (!oit.moveNext()) {
      return false;
    }
    if (!eq(it.current(), oit.current())) {
      return false;
    }
  }
  return !oit.moveNext();
}
Name Type(s) Description other Sequence

The other sequence to compare this one to.

equalityFn Function?

An optional equality function, which should take two arguments and return true or false to indicate whether those values are considered equal.

returns boolean

Whether the two sequences contain the same values in the same order.

Examples
Lazy([1, 2]).equals(Lazy([1, 2]))   
Lazy([1, 2]).equals(Lazy([2, 1]))   
Lazy([1]).equals(Lazy([1, 2]))      
Lazy([1, 2]).equals(Lazy([1]))      
Lazy([]).equals(Lazy([]))           
Lazy(['foo']).equals(Lazy(['foo'])) 
Lazy(['1']).equals(Lazy([1]))       
Lazy([false]).equals(Lazy([0]))     
Lazy([1, 2]).equals([1, 2])         
Lazy([1, 2]).equals('[1, 2]')       
every Sequence#every

aliases: all

Checks whether every element in this sequence satisfies a given predicate.

Signature
Sequence.every = function(predicate) {  }
Sequence.every = function every(predicate) {
  predicate = createCallback(predicate);

  return this.each(function(e, i) {
    return !!predicate(e, i);
  });
}
Name Type(s) Description predicate Function

A function to call on (potentially) every element in this sequence.

returns boolean

True if predicate returns true for every element in the sequence (or the sequence is empty). False if predicate returns false for at least one element.

Examples
var numbers = [1, 2, 3, 4, 5];

var objects = [{ foo: true }, { foo: false, bar: true }];

Lazy(numbers).every(isEven)     
Lazy(numbers).every(isPositive) 
Lazy(objects).all('foo')        
Lazy(objects).all('bar')        
filter Sequence#filter

aliases: select

Creates a new sequence whose values are the elements of this sequence which satisfy the specified predicate.

Signature
Sequence.filter = function(filterFn) {  }
Sequence.filter = function filter(filterFn) {
  return new FilteredSequence(this, createCallback(filterFn));
}
Name Type(s) Description filterFn Function

The predicate to call on each element in this sequence, which returns true if the element should be included.

returns Sequence

The new sequence.

Examples
var numbers = [1, 2, 3, 4, 5, 6];

Lazy(numbers).filter(isEven) 
Benchmarks
function isEven(x) { return x % 2 === 0; }

var smArr = Lazy.range(10).toArray(),
    lgArr = Lazy.range(100).toArray();

Lazy(smArr).filter(isEven).each(Lazy.noop) 
Lazy(lgArr).filter(isEven).each(Lazy.noop) 
_.each(_.filter(smArr, isEven), _.noop)    
_.each(_.filter(lgArr, isEven), _.noop)    
Implementation 10 elements 100 elements lazy lodash find Sequence#find

aliases: detect

Seaches for the first element in the sequence satisfying a given predicate.

Signature
Sequence.find = function(predicate) {  }
Sequence.find = function find(predicate) {
  return this.filter(predicate).first();
}
Name Type(s) Description predicate Function

A function to call on (potentially) every element in the sequence.

returns *

The first element in the sequence for which predicate returns true, or undefined if no such element is found.

Examples
function divisibleBy3(x) {
  return x % 3 === 0;
}

var numbers = [5, 6, 7, 8, 9, 10];

Lazy(numbers).find(divisibleBy3) 
Lazy(numbers).find(isNegative)   
findWhere Sequence#findWhere

Returns the first element in this sequence with property names and values matching those of the specified object.

Signature
Sequence.findWhere = function(properties) {  }
Sequence.findWhere = function findWhere(properties) {
  return this.where(properties).first();
}
Name Type(s) Description properties Object

The properties that should be found on some element in this sequence.

returns *

The found element, or undefined if none exists in this sequence.

Examples
var words = ["foo", "bar"];

Lazy(words).findWhere({ 0: "f" }); 
Lazy(words).findWhere({ 0: "z" }); 
first Sequence#first

aliases: head take

Creates a new sequence comprising the first N elements from this sequence, OR (if N is undefined) simply returns the first element of this sequence.

Signature
Sequence.first = function(count) {  }
Sequence.first = function first(count) {
  if (typeof count === "undefined") {
    return getFirst(this);
  }
  return new TakeSequence(this, count);
}
Name Type(s) Description count number?

The number of elements to take from this sequence. If this value exceeds the length of the sequence, the resulting sequence will be essentially the same as this one.

returns *

The new sequence (or the first element from this sequence if no count was given).

Examples
function powerOfTwo(exp) {
  return Math.pow(2, exp);
}

Lazy.generate(powerOfTwo).first()          
Lazy.generate(powerOfTwo).first(5)         
Lazy.generate(powerOfTwo).skip(2).first()  
Lazy.generate(powerOfTwo).skip(2).first(2) 
flatten Sequence#flatten

Creates a new sequence with every element from this sequence, and with arrays exploded so that a sequence of arrays (of arrays) becomes a flat sequence of values.

Signature
Sequence.flatten = function(shallow) {  }
Sequence.flatten = function flatten(shallow) {
  return new FlattenedSequence(this, shallow);
}
Name Type(s) Description shallow boolean

Option to flatten only one level deep (default is recursive).

returns Sequence

The new sequence.

Examples
Lazy([1, [2, 3], [4, [5]]]).flatten()     
Lazy([1, [2, 3], [4, [5]]]).flatten(true) 
Lazy([1, Lazy([2, 3])]).flatten()         
get Sequence#get

Returns the element at the specified index. Note that, for sequences that are not ArrayLikeSequences, this may require partially evaluating the sequence, iterating to reach the result. (In other words for such sequences this method is not O(1).)

Signature
Sequence.get = function(i) {  }
Sequence.get = function get(i) {
  var element;
  this.each(function(e, index) {
    if (index === i) {
      element = e;
      return false;
    }
  });
  return element;
}
Name Type(s) Description i number

The index to access.

returns *

The element.

getIterator Sequence#getIterator

Creates an Iterator object with two methods, moveNext -- returning true or false -- and current -- returning the current value.

This method is used when asynchronously iterating over sequences. Any type inheriting from Sequence must implement this method or it can't support asynchronous iteration.

Note that this method is not intended to be used directly by application code. Rather, it is intended as a means for implementors to potentially define custom sequence types that support either synchronous or asynchronous iteration.

Signature
Sequence.getIterator = function() {  }
Sequence.getIterator = function getIterator() {
  return new Iterator(this);
}
Name Type(s) Description returns Iterator

An iterator object.

Examples
var iterator = Lazy([1, 2]).getIterator();

iterator.moveNext(); 
iterator.current();  
iterator.moveNext(); 
iterator.current();  
iterator.moveNext(); 
groupBy Sequence#groupBy

Creates a new ObjectLikeSequence comprising the elements in this one, grouped together according to some key. The value associated with each key in the resulting object-like sequence is an array containing all of the elements in this sequence with that key.

Signature
Sequence.groupBy = function(keyFn, valFn) {  }
Sequence.groupBy = function groupBy(keyFn, valFn) {
  return new GroupedSequence(this, keyFn, valFn);
}
Name Type(s) Description keyFn Function|string

The function to call on the elements in this sequence to obtain a key by which to group them, or a string representing a parameter to read from all the elements in this sequence.

valFn Function|string

(Optional) The function to call on the elements in this sequence to assign to the value for each instance to appear in the group, or a string representing a parameter to read from all the elements in this sequence.

returns ObjectLikeSequence

The new sequence.

Examples
function oddOrEven(x) {
  return x % 2 === 0 ? 'even' : 'odd';
}
function square(x) {
  return x*x;
}

var numbers = [1, 2, 3, 4, 5];

Lazy(numbers).groupBy(oddOrEven)                     
Lazy(numbers).groupBy(oddOrEven).get("odd")          
Lazy(numbers).groupBy(oddOrEven).get("foo")          
Lazy(numbers).groupBy(oddOrEven, square).get("even") 

Lazy([
  { name: 'toString' },
  { name: 'toString' }
]).groupBy('name');

  'toString': [
    { name: 'toString' },
    { name: 'toString' }
  ]
}
indexBy Sequence#indexBy

Creates a new ObjectLikeSequence comprising the elements in this one, indexed according to some key.

Signature
Sequence.indexBy = function(keyFn, valFn) {  }
Sequence.indexBy = function(keyFn, valFn) {
  return new IndexedSequence(this, keyFn, valFn);
}
Name Type(s) Description keyFn Function|string

The function to call on the elements in this sequence to obtain a key by which to index them, or a string representing a property to read from all the elements in this sequence.

valFn Function|string

(Optional) The function to call on the elements in this sequence to assign to the value of the indexed object, or a string representing a parameter to read from all the elements in this sequence.

returns Sequence

The new sequence.

Examples
var people = [
  { name: 'Bob', age: 25 },
  { name: 'Fred', age: 34 }
];

var bob  = people[0],
    fred = people[1];

Lazy(people).indexBy('name')        
Lazy(people).indexBy('name', 'age') 
indexOf Sequence#indexOf

Performs (at worst) a linear search from the head of this sequence, returning the first index at which the specified value is found.

Signature
Sequence.indexOf = function(value, equalityFn) {  }
Sequence.indexOf = function indexOf(value, equalityFn) {
  var eq = equalityFn || Lazy.equality,
      foundIndex = -1;

  this.each(function(e, i) {
    if (eq(e, value)) {
      foundIndex = i;
      return false;
    }
  });
  return foundIndex;
}
Name Type(s) Description value *

The element to search for in the sequence.

equalityFn Function?

An optional equality function, which should take two arguments and return true or false to indicate whether those values are considered equal.

returns number

The index within this sequence where the given value is located, or -1 if the sequence doesn't contain the value.

Examples
function reciprocal(x) { return 1 / x; }

Lazy(["foo", "bar", "baz"]).indexOf("bar")   
Lazy([1, 2, 3]).indexOf(4)                   
Lazy([1, 2, 3]).map(reciprocal).indexOf(0.5) 
initial Sequence#initial

Creates a new sequence comprising all but the last N elements of this sequence.

Signature
Sequence.initial = function(count) {  }
Sequence.initial = function initial(count) {
  return new InitialSequence(this, count);
}
Name Type(s) Description count number?

The number of items to omit from the end of the sequence (defaults to 1).

returns Sequence

The new sequence.

Examples
Lazy([1, 2, 3, 4]).initial()                    
Lazy([1, 2, 3, 4]).initial(2)                   
Lazy([1, 2, 3]).filter(Lazy.identity).initial() 
intersection Sequence#intersection

Creates a new sequence with all the elements of this sequence that also appear among the specified arguments.

Signature
Sequence.intersection = function(var_args) {  }
Sequence.intersection = function intersection(var_args) {
  if (arguments.length === 1 && isArray(arguments[0])) {
    return new SimpleIntersectionSequence(this, ( var_args));
  } else {
    return new IntersectionSequence(this, arraySlice.call(arguments, 0));
  }
}
Name Type(s) Description var_args ...*

The values, or array(s) of values, in which elements from this sequence must also be included to end up in the resulting sequence.

returns Sequence

The new sequence.

Examples
Lazy(["foo", "bar"]).intersection([])             
Lazy(["foo", "bar"]).intersection(["bar", "baz"]) 
Lazy(["a", "a"]).intersection(["a"])              
Lazy(["a"]).intersection(["a", "a"])              
Lazy(["a", "a"]).intersection(["a", "a"])         
Lazy(["a", "a"]).intersection(["a"], ["a"])       
invoke Sequence#invoke

Creates a new sequence whose values are calculated by invoking the specified function on each element in this sequence.

Signature
Sequence.invoke = function(methodName) {  }
Sequence.invoke = function invoke(methodName) {
  return this.map(function(e) {
    return e[methodName]();
  });
}
Name Type(s) Description methodName string

The name of the method to invoke for every element in this sequence.

returns Sequence

The new sequence.

Examples
function Person(first, last) {
  this.fullName = function fullName() {
    return first + " " + last;
  };
}

var people = [
  new Person("Dan", "Tao"),
  new Person("Bob", "Smith")
];

Lazy(people).invoke("fullName") 
isEmpty Sequence#isEmpty

Checks whether the sequence has no elements.

Signature
Sequence.isEmpty = function() {  }
Sequence.isEmpty = function isEmpty() {
  return !this.any();
}
Name Type(s) Description returns boolean

True if the sequence is empty, false if it contains at least one element.

Examples
Lazy([]).isEmpty()        
Lazy([1, 2, 3]).isEmpty() 
join Sequence#join

aliases: toString

Creates a string from joining together all of the elements in this sequence, separated by the given delimiter.

Signature
Sequence.join = function(delimiter) {  }
Sequence.join = function join(delimiter) {
  delimiter = typeof delimiter === "undefined" ? "," : String(delimiter);

  var i = -1;
  return this.reduce(function(str, e) {
    if (++i > 0) {
      str += delimiter;
    }
    return str + e;
  }, "");
}
Name Type(s) Description delimiter string?

The separator to insert between every element from this sequence in the resulting string (defaults to ",").

returns string

The delimited string.

Examples
function toParam(v, k) {
  return k + '=' + v;
}

Lazy([6, 29, 1984]).join("/")  
Lazy(["a", "b", "c"]).join()   
Lazy(["a", "b", "c"]).join("") 
Lazy([1, 2, 3]).join()         
Lazy([1, 2, 3]).join("")       
Lazy(["", "", ""]).join(",")   
Lazy([1, 2]).join(0)           
Lazy(["cons", "d"]).join(true) 
Lazy({foo: 1, bar: 2}).values().join()        
Lazy({foo: 1, bar: 2}).keys().join()          
Lazy({foo: 1, bar: 2}).map(toParam).join('&') 
last Sequence#last

Creates a new sequence comprising the last N elements of this sequence, OR (if N is undefined) simply returns the last element of this sequence.

Signature
Sequence.last = function(count) {  }
Sequence.last = function last(count) {
  if (typeof count === "undefined") {
    return this.reverse().first();
  }
  return this.reverse().take(count).reverse();
}
Name Type(s) Description count number?

The number of items to take from the end of the sequence.

returns *

The new sequence (or the last element from this sequence if no count was given).

Examples
Lazy([1, 2, 3]).last()                 
Lazy([1, 2, 3]).last(2)                
Lazy([1, 2, 3]).filter(isEven).last(2) 
lastIndexOf Sequence#lastIndexOf

Performs (at worst) a linear search from the tail of this sequence, returning the last index at which the specified value is found.

Signature
Sequence.lastIndexOf = function(value) {  }
Sequence.lastIndexOf = function lastIndexOf(value, equalityFn) {
  var reversed = this.getIndex().reverse(),
      index    = reversed.indexOf(value, equalityFn);
  if (index !== -1) {
    index = reversed.length() - index - 1;
  }
  return index;
}
Name Type(s) Description value *

The element to search for in the sequence.

returns number

The last index within this sequence where the given value is located, or -1 if the sequence doesn't contain the value.

Examples
Lazy(["a", "b", "c", "b", "a"]).lastIndexOf("b")    
Lazy([1, 2, 3]).lastIndexOf(0)                      
Lazy([2, 2, 1, 2, 4]).filter(isEven).lastIndexOf(2) 
map Sequence#map

aliases: collect

Creates a new sequence whose values are calculated by passing this sequence's elements through some mapping function.

Signature
Sequence.map = function(mapFn) {  }
Sequence.map = function map(mapFn) {
  return new MappedSequence(this, createCallback(mapFn));
}
Name Type(s) Description mapFn Function

The mapping function used to project this sequence's elements onto a new sequence. This function takes up to two arguments: the element, and the current index.

returns Sequence

The new sequence.

Examples
function addIndexToValue(e, i) { return e + i; }

Lazy([]).map(increment)              
Lazy([1, 2, 3]).map(increment)       
Lazy([1, 2, 3]).map(addIndexToValue) 
Benchmarks
function increment(x) { return x + 1; }

var smArr = Lazy.range(10).toArray(),
    lgArr = Lazy.range(100).toArray();

Lazy(smArr).map(increment).each(Lazy.noop) 
Lazy(lgArr).map(increment).each(Lazy.noop) 
_.each(_.map(smArr, increment), _.noop)    
_.each(_.map(lgArr, increment), _.noop)    
Implementation 10 elements 100 elements lazy lodash max Sequence#max

Gets the maximum value in the sequence.

Signature
Sequence.max = function(valueFn) {  }
Sequence.max = function max(valueFn) {
  if (typeof valueFn !== "undefined") {
    return this.maxBy(valueFn);
  }

  return this.reduce(function(prev, current, i) {
    if (typeof prev === "undefined") {
      return current;
    }
    return current > prev ? current : prev;
  });
}
Name Type(s) Description valueFn Function?

The function by which the value for comparison is calculated for each element in the sequence.

returns *

The element with the highest value in the sequence, or undefined if the sequence is empty.

Examples
function reverseDigits(x) {
  return Number(String(x).split('').reverse().join(''));
}

Lazy([]).max()                              
Lazy([1]).max()                             
Lazy([1, 2]).max()                          
Lazy([2, 1]).max()                          
Lazy([6, 18, 2, 48, 29]).max()              
Lazy([6, 18, 2, 48, 29]).max(reverseDigits) 
Lazy(['b', 'c', 'a']).max()                 
memoize Sequence#memoize

Provides an indexed, memoized view into the sequence. This will cache the result whenever the sequence is first iterated, so that subsequent iterations will access the same element objects.

Signature
Sequence.memoize = function() {  }
Sequence.memoize = function memoize() {
  return new MemoizedSequence(this);
}
Name Type(s) Description returns ArrayLikeSequence

An indexed, memoized sequence containing this sequence's elements, cached after the first iteration.

Examples
function createObject() { return new Object(); }

var plain    = Lazy.generate(createObject, 10),
    memoized = Lazy.generate(createObject, 10).memoize();

plain.toArray()[0] === plain.toArray()[0];       
memoized.toArray()[0] === memoized.toArray()[0]; 
min Sequence#min

Gets the minimum value in the sequence.

Signature
Sequence.min = function(valueFn) {  }
Sequence.min = function min(valueFn) {
  if (typeof valueFn !== "undefined") {
    return this.minBy(valueFn);
  }

  return this.reduce(function(prev, current, i) {
    if (typeof prev === "undefined") {
      return current;
    }
    return current < prev ? current : prev;
  });
}
Name Type(s) Description valueFn Function?

The function by which the value for comparison is calculated for each element in the sequence.

returns *

The element with the lowest value in the sequence, or undefined` if the sequence is empty.

Examples
function negate(x) { return x * -1; }

Lazy([]).min()                       
Lazy([1]).min()                      
Lazy([1, 2]).min()                   
Lazy([2, 1]).min()                   
Lazy([6, 18, 2, 49, 34]).min()       
Lazy([6, 18, 2, 49, 34]).min(negate) 
Lazy(['b', 'a', 'c']).min()          
none Sequence#none

Checks whether NO elements in this sequence satisfy the given predicate (the opposite of Sequence#all, basically).

Signature
Sequence.none = function(predicate) {  }
Sequence.none = function none(predicate) {
  return !this.any(predicate);
}
Name Type(s) Description predicate Function?

A function to call on (potentially) every element in this sequence.

returns boolean

True if predicate does not return true for any element in the sequence. False if predicate returns true for at least one element.

Examples
var numbers = [1, 2, 3, 4, 5];

Lazy(numbers).none()           
Lazy(numbers).none(isEven)     
Lazy(numbers).none(isNegative) 
Lazy([]).none(isEven)          
Lazy([]).none(isNegative)      
Lazy([]).none()                
ofType Sequence#ofType

Creates a new sequence whose values have the specified type, as determined by the typeof operator.

Signature
Sequence.ofType = function(type) {  }
Sequence.ofType = function ofType(type) {
  return this.filter(function(e) { return typeof e === type; });
}
Name Type(s) Description type string

The type of elements to include from the underlying sequence, i.e. where typeof [element] === [type].

returns Sequence

The new sequence, comprising elements of the specified type.

Examples
Lazy([1, 2, 'foo', 'bar']).ofType('number')  
Lazy([1, 2, 'foo', 'bar']).ofType('string')  
Lazy([1, 2, 'foo', 'bar']).ofType('boolean') 
pluck Sequence#pluck

Creates a new sequence whose values are calculated by accessing the specified property from each element in this sequence.

Signature
Sequence.pluck = function(propertyName) {  }
Sequence.pluck = function pluck(property) {
  return this.map(property);
}
Name Type(s) Description propertyName string

The name of the property to access for every element in this sequence.

returns Sequence

The new sequence.

Examples
var people = [
  { first: "Dan", last: "Tao" },
  { first: "Bob", last: "Smith" }
];

Lazy(people).pluck("last") 
reduce Sequence#reduce

aliases: inject foldl

Aggregates a sequence into a single value according to some accumulator function.

For an asynchronous sequence, instead of immediately returning a result (which it can't, obviously), this method returns an AsyncHandle whose onComplete method can be called to supply a callback to handle the final result once iteration has completed.

Signature
Sequence.reduce = function(aggregator, memo) {  }
Sequence.reduce = function reduce(aggregator, memo) {
  if (arguments.length < 2) {
    return this.tail().reduce(aggregator, this.head());
  }

  var eachResult = this.each(function(e, i) {
    memo = aggregator(memo, e, i);
  });

  
  if (eachResult instanceof AsyncHandle) {
    return eachResult.then(function() { return memo; });
  }

  return memo;
}
Name Type(s) Description aggregator Function

The function through which to pass every element in the sequence. For every element, the function will be passed the total aggregated result thus far and the element itself, and should return a new aggregated result.

memo *?

The starting value to use for the aggregated result (defaults to the first element in the sequence).

returns *

The result of the aggregation, or, for asynchronous sequences, an AsyncHandle whose onComplete method accepts a callback to handle the final result.

Examples
function multiply(x, y) { return x * y; }

var numbers = [1, 2, 3, 4];

Lazy(numbers).reduce(multiply)    
Lazy(numbers).reduce(multiply, 5) 
reduceRight Sequence#reduceRight

aliases: foldr

Aggregates a sequence, from the tail, into a single value according to some accumulator function.

Signature
Sequence.reduceRight = function(aggregator, memo) {  }
Sequence.reduceRight = function reduceRight(aggregator, memo) {
  if (arguments.length < 2) {
    return this.initial(1).reduceRight(aggregator, this.last());
  }

  
  
  var indexed = this.getIndex(),
      i = indexed.length() - 1;
  return indexed.reverse().reduce(function(m, e) {
    return aggregator(m, e, i--);
  }, memo);
}
Name Type(s) Description aggregator Function

The function through which to pass every element in the sequence. For every element, the function will be passed the total aggregated result thus far and the element itself, and should return a new aggregated result.

memo *

The starting value to use for the aggregated result.

returns *

The result of the aggregation.

Examples
function append(s1, s2) {
  return s1 + s2;
}

function isVowel(str) {
  return "aeiou".indexOf(str) !== -1;
}

Lazy("abcde").reduceRight(append)                 
Lazy("abcde").filter(isVowel).reduceRight(append) 
reject Sequence#reject

Creates a new sequence whose values exclude the elements of this sequence identified by the specified predicate.

Signature
Sequence.reject = function(rejectFn) {  }
Sequence.reject = function reject(rejectFn) {
  rejectFn = createCallback(rejectFn);
  return this.filter(function(e) { return !rejectFn(e); });
}
Name Type(s) Description rejectFn Function

The predicate to call on each element in this sequence, which returns true if the element should be omitted.

returns Sequence

The new sequence.

Examples
Lazy([1, 2, 3, 4, 5]).reject(isEven)              
Lazy([{ foo: 1 }, { bar: 2 }]).reject('foo')      
Lazy([{ foo: 1 }, { foo: 2 }]).reject({ foo: 2 }) 
rest Sequence#rest

aliases: skip tail rest

Creates a new sequence comprising all but the first N elements of this sequence.

Signature
Sequence.rest = function(count) {  }
Sequence.rest = function rest(count) {
  return new DropSequence(this, count);
}
Name Type(s) Description count number?

The number of items to omit from the beginning of the sequence (defaults to 1).

returns Sequence

The new sequence.

Examples
Lazy([1, 2, 3, 4]).rest()  
Lazy([1, 2, 3, 4]).rest(0) 
Lazy([1, 2, 3, 4]).rest(2) 
Lazy([1, 2, 3, 4]).rest(5) 
reverse Sequence#reverse

Creates a new sequence with the same elements as this one, but to be iterated in the opposite order.

Note that in some (but not all) cases, the only way to create such a sequence may require iterating the entire underlying source when each is called.

Signature
Sequence.reverse = function() {  }
Sequence.reverse = function reverse() {
  return new ReversedSequence(this);
}
Name Type(s) Description returns Sequence

The new sequence.

Examples
Lazy([1, 2, 3]).reverse() 
Lazy([]).reverse()        
shuffle Sequence#shuffle

Creates a new sequence with the same elements as this one, in a randomized order.

Signature
Sequence.shuffle = function() {  }
Sequence.shuffle = function shuffle() {
  return new ShuffledSequence(this);
}
Name Type(s) Description returns Sequence

The new sequence.

Examples
Lazy([1, 2, 3, 4, 5]).shuffle().value() 
Lazy([]).shuffle().value()              
Lazy([1]).shuffle().each(Lazy.noop)     
Lazy([]).shuffle().each(Lazy.noop)      
size Sequence#size

Gets the number of elements in the sequence. In some cases, this may require eagerly evaluating the sequence.

Signature
Sequence.size = function() {  }
Sequence.size = function size() {
  return this.getIndex().length();
}
Name Type(s) Description returns number

The number of elements in the sequence.

Examples
Lazy([1, 2, 3]).size();                 
Lazy([1, 2]).map(Lazy.identity).size(); 
Lazy([1, 2, 3]).reject(isEven).size();  
Lazy([1, 2, 3]).take(1).size();         
Lazy({ foo: 1, bar: 2 }).size();        
Lazy('hello').size();                   
some Sequence#some

aliases: any

Checks whether at least one element in this sequence satisfies a given predicate (or, if no predicate is specified, whether the sequence contains at least one element).

Signature
Sequence.some = function(predicate) {  }
Sequence.some = function some(predicate) {
  predicate = createCallback(predicate, true);

  var success = false;
  this.each(function(e) {
    if (predicate(e)) {
      success = true;
      return false;
    }
  });
  return success;
}
Name Type(s) Description predicate Function?

A function to call on (potentially) every element in this sequence.

returns boolean

True if predicate returns true for at least one element in the sequence. False if predicate returns false for every element (or the sequence is empty).

Examples
var numbers = [1, 2, 3, 4, 5];

Lazy(numbers).some()           
Lazy(numbers).some(isEven)     
Lazy(numbers).some(isNegative) 
Lazy([]).some()                
sort Sequence#sort

Creates a new sequence with the same elements as this one, but ordered using the specified comparison function.

This has essentially the same behavior as calling Array#sort, but obviously instead of modifying the collection it returns a new Sequence object.

Signature
Sequence.sort = function(sortFn, descending) {  }
Sequence.sort = function sort(sortFn, descending) {
  sortFn || (sortFn = compare);
  if (descending) { sortFn = reverseArguments(sortFn); }
  return new SortedSequence(this, sortFn);
}
Name Type(s) Description sortFn Function?

The function used to compare elements in the sequence. The function will be passed two elements and should return:

- 1 if the first is greater
- -1 if the second is greater
- 0 if the two values are the same
descending boolean

Whether or not the resulting sequence should be in descending order (defaults to false).

returns Sequence

The new sequence.

Examples
Lazy([5, 10, 1]).sort()                
Lazy(['foo', 'bar']).sort()            
Lazy(['b', 'c', 'a']).sort(null, true) 
Lazy([5, 10, 1]).sort(null, true)      


Lazy(['a', 'ab', 'aa', 'ba', 'b', 'abc']).sort(function compare(x, y) {
  if (x.length && (x.length !== y.length)) { return compare(x.length, y.length); }
  if (x === y) { return 0; }
  return x > y ? 1 : -1;
});
sortBy Sequence#sortBy

Creates a new sequence with the same elements as this one, but ordered by the results of the given function.

You can pass:

Signature
Sequence.sortBy = function(sortFn, descending) {  }
Sequence.sortBy = function sortBy(sortFn, descending) {
  sortFn = createComparator(sortFn);
  if (descending) { sortFn = reverseArguments(sortFn); }
  return new SortedSequence(this, sortFn);
}
Name Type(s) Description sortFn Function

The function to call on the elements in this sequence, in order to sort them.

descending boolean

Whether or not the resulting sequence should be in descending order (defaults to false).

returns Sequence

The new sequence.

Examples
function population(country) {
  return country.pop;
}

function area(country) {
  return country.sqkm;
}

var countries = [
  { name: "USA", pop: 320000000, sqkm: 9600000 },
  { name: "Brazil", pop: 194000000, sqkm: 8500000 },
  { name: "Nigeria", pop: 174000000, sqkm: 924000 },
  { name: "China", pop: 1350000000, sqkm: 9700000 },
  { name: "Russia", pop: 143000000, sqkm: 17000000 },
  { name: "Australia", pop: 23000000, sqkm: 7700000 }
];

Lazy(countries).sortBy(population).last(3).pluck('name') 
Lazy(countries).sortBy(area).last(3).pluck('name')       
Lazy(countries).sortBy(area, true).first(3).pluck('name') 
Benchmarks
var randoms = Lazy.generate(Math.random).take(100).toArray();

Lazy(randoms).sortBy(Lazy.identity).each(Lazy.noop) 
_.each(_.sortBy(randoms, Lazy.identity), _.noop)    
Implementation Ops/second lazy lodash sortedIndex Sequence#sortedIndex

Performs a binary search of this sequence, returning the lowest index where the given value is either found, or where it belongs (if it is not already in the sequence).

This method assumes the sequence is in sorted order and will fail otherwise.

Signature
Sequence.sortedIndex = function(value) {  }
Sequence.sortedIndex = function sortedIndex(value) {
  var indexed = this.getIndex(),
      lower   = 0,
      upper   = indexed.length(),
      i;

  while (lower < upper) {
    i = (lower + upper) >>> 1;
    if (compare(indexed.get(i), value) === -1) {
      lower = i + 1;
    } else {
      upper = i;
    }
  }
  return lower;
}
Name Type(s) Description value *

The element to search for in the sequence.

returns number

An index within this sequence where the given value is located, or where it belongs in sorted order.

Examples
Lazy([1, 3, 6, 9]).sortedIndex(3)                    
Lazy([1, 3, 6, 9]).sortedIndex(7)                    
Lazy([5, 10, 15, 20]).filter(isEven).sortedIndex(10) 
Lazy([5, 10, 15, 20]).filter(isEven).sortedIndex(12) 
sum Sequence#sum

Gets the sum of the numeric values in the sequence.

Signature
Sequence.sum = function(valueFn) {  }
Sequence.sum = function sum(valueFn) {
  if (typeof valueFn !== "undefined") {
    return this.sumBy(valueFn);
  }

  return this.reduce(function(x, y) { return x + y; }, 0);
}
Name Type(s) Description valueFn Function?

The function used to select the numeric values that will be summed up.

returns *

The sum.

Examples
Lazy([]).sum()                     
Lazy([1, 2, 3, 4]).sum()           
Lazy([1.2, 3.4]).sum(Math.floor)   
Lazy(['foo', 'bar']).sum('length') 
takeWhile Sequence#takeWhile

Creates a new sequence comprising the elements from the head of this sequence that satisfy some predicate. Once an element is encountered that doesn't satisfy the predicate, iteration will stop.

Signature
Sequence.takeWhile = function(predicate) {  }
Sequence.takeWhile = function takeWhile(predicate) {
  return new TakeWhileSequence(this, predicate);
}
Name Type(s) Description predicate Function returns Sequence

The new sequence

Examples
function lessThan(x) {
  return function(y) {
    return y < x;
  };
}

Lazy([1, 2, 3, 4]).takeWhile(lessThan(3)) 
Lazy([1, 2, 3, 4]).takeWhile(lessThan(0)) 
tap Sequence#tap

Passes each element in the sequence to the specified callback during iteration. This is like Sequence#each, except that it can be inserted anywhere in the middle of a chain of methods to "intercept" the values in the sequence at that point.

Signature
Sequence.tap = function(callback) {  }
Sequence.tap = function tap(callback) {
  return new TappedSequence(this, callback);
}
Name Type(s) Description callback Function

A function to call on every element in the sequence during iteration. The return value of this function does not matter.

returns Sequence

A sequence comprising the same elements as this one.

Examples
Lazy([1, 2, 3]).tap(fn).each(Lazy.noop); 
toArray Sequence#toArray

Creates an array snapshot of a sequence.

Note that for indefinite sequences, this method may raise an exception or (worse) cause the environment to hang.

Signature
Sequence.toArray = function() {  }
Sequence.toArray = function toArray() {
  return this.reduce(function(arr, element) {
    arr.push(element);
    return arr;
  }, []);
}
Name Type(s) Description returns Array

An array containing the current contents of the sequence.

Examples
Lazy([1, 2, 3]).toArray() 
toObject Sequence#toObject

Creates an object from a sequence of key/value pairs.

Signature
Sequence.toObject = function() {  }
Sequence.toObject = function toObject() {
  return this.reduce(function(object, pair) {
    object[pair[0]] = pair[1];
    return object;
  }, {});
}
Name Type(s) Description returns Object

An object with keys and values corresponding to the pairs of elements in the sequence.

Examples
var details = [
  ["first", "Dan"],
  ["last", "Tao"],
  ["age", 29]
];

Lazy(details).toObject() 
union Sequence#union

Creates a new sequence with all the unique elements either in this sequence or among the specified arguments.

Signature
Sequence.union = function(var_args) {  }
Sequence.union = function union(var_args) {
  return this.concat(var_args).uniq();
}
Name Type(s) Description var_args ...*

The values, or array(s) of values, to be additionally included in the resulting sequence.

returns Sequence

The new sequence.

Examples
Lazy(["foo", "bar"]).union([])             
Lazy(["foo", "bar"]).union(["bar", "baz"]) 
uniq Sequence#uniq

aliases: unique

Creates a new sequence with every unique element from this one appearing exactly once (i.e., with duplicates removed).

Signature
Sequence.uniq = function(keyFn) {  }
Sequence.uniq = function uniq(keyFn) {
  return new UniqueSequence(this, keyFn);
}
Name Type(s) Description keyFn Function?

An optional function to produce the key for each object. This key is then tested for uniqueness as opposed to the object reference.

returns Sequence

The new sequence.

Examples
Lazy([1, 2, 2, 3, 3, 3]).uniq() 
Lazy([{ name: 'mike' }, 
    { name: 'sarah' }, 
    { name: 'mike' }
]).uniq('name')
Benchmarks
function randomOf(array) {
  return function() {
    return array[Math.floor(Math.random() * array.length)];
  };
}

var mostUnique = Lazy.generate(randomOf(_.range(100)), 100).toArray(),
    someUnique = Lazy.generate(randomOf(_.range(50)), 100).toArray(),
    mostDupes  = Lazy.generate(randomOf(_.range(5)), 100).toArray();

Lazy(mostUnique).uniq().each(Lazy.noop) 
Lazy(someUnique).uniq().each(Lazy.noop) 
Lazy(mostDupes).uniq().each(Lazy.noop)  
_.each(_.uniq(mostUnique), _.noop)      
_.each(_.uniq(someUnique), _.noop)      
_.each(_.uniq(mostDupes), _.noop)       
Implementation mostly unique elements some unique elements mostly duplicate elements lazy lodash where Sequence#where

Creates a new sequence whose values are the elements of this sequence with property names and values matching those of the specified object.

Signature
Sequence.where = function(properties) {  }
Sequence.where = function where(properties) {
  return this.filter(properties);
}
Name Type(s) Description properties Object

The properties that should be found on every element that is to be included in this sequence.

returns Sequence

The new sequence.

Examples
var people = [
  { first: "Dan", last: "Tao" },
  { first: "Bob", last: "Smith" }
];

Lazy(people).where({ first: "Dan" }) 
Benchmarks
var animals = ["dog", "cat", "mouse", "horse", "pig", "snake"];

Lazy(animals).where({ length: 3 }).each(Lazy.noop) 
_.each(_.where(animals, { length: 3 }), _.noop)    
Implementation Ops/second lazy lodash without Sequence#without

aliases: difference

Creates a new sequence with all the elements of this sequence that are not also among the specified arguments.

Signature
Sequence.without = function(var_args) {  }
Sequence.without = function without(var_args) {
  return new WithoutSequence(this, arraySlice.call(arguments, 0));
}
Name Type(s) Description var_args ...*

The values, or array(s) of values, to be excluded from the resulting sequence.

returns Sequence

The new sequence.

Examples
Lazy([1, 2, 3, 4, 5]).without(2, 3)   
Lazy([1, 2, 3, 4, 5]).without([4, 5]) 
zip Sequence#zip

Creates a new sequence by combining the elements from this sequence with corresponding elements from the specified array(s).

Signature
Sequence.zip = function(var_args) {  }
Sequence.zip = function zip(var_args) {
  if (arguments.length === 1) {
    return new SimpleZippedSequence(this, ( var_args));
  } else {
    return new ZippedSequence(this, arraySlice.call(arguments, 0));
  }
}
Name Type(s) Description var_args ...Array

One or more arrays of elements to combine with those of this sequence.

returns Sequence

The new sequence.

Examples
Lazy([1, 2]).zip([3, 4])     
Lazy([]).zip([0])            
Lazy([0]).zip([])            
Lazy([]).zip([1, 2], [3, 4]) 
Lazy([]).zip([1], [2, 3])    
Lazy([1, 2]).zip([3], [4])   
Benchmarks
var smArrL = Lazy.range(10).toArray(),
    smArrR = Lazy.range(10, 20).toArray(),
    lgArrL = Lazy.range(100).toArray(),
    lgArrR = Lazy.range(100, 200).toArray();

Lazy(smArrL).zip(smArrR).each(Lazy.noop) 
Lazy(lgArrL).zip(lgArrR).each(Lazy.noop) 
_.each(_.zip(smArrL, smArrR), _.noop)    
_.each(_.zip(lgArrL, lgArrR), _.noop)    
Implementation zipping 10-element arrays zipping 100-element arrays lazy lodash ArrayLikeSequence ArrayLikeSequence

An ArrayLikeSequence is a Sequence that provides random access to its elements. This extends the API for iterating with the additional methods #get and #length, allowing a sequence to act as a "view" into a collection or other indexed data source.

The initial sequence created by wrapping an array with Lazy(array) is an ArrayLikeSequence.

All methods of ArrayLikeSequence that conceptually should return something like a array (with indexed access) return another ArrayLikeSequence, for example:

The above is not an exhaustive list. There are also certain other cases where it might be possible to return an ArrayLikeSequence (e.g., calling Sequence#concat with a single array argument), but this is not guaranteed by the API.

Note that in many cases, it is not possible to provide indexed access without first performing at least a partial iteration of the underlying sequence. In these cases an ArrayLikeSequence will not be returned:

etc. The above methods only return ordinary Sequence objects.

Defining custom array-like sequences

Creating a custom ArrayLikeSequence is essentially the same as creating a custom Sequence. You just have a couple more methods you need to implement: get and (optionally) length.

Here's an example. Let's define a sequence type called OffsetSequence that offsets each of its parent's elements by a set distance, and circles back to the beginning after reaching the end. Remember: the initialization function you pass to #define should always accept a parent as its first parameter.

ArrayLikeSequence.define("offset", {
  init: function(parent, offset) {
    this.offset = offset;
  },

  get: function(i) {
    return this.parent.get((i + this.offset) % this.parent.length());
  }
});

It's worth noting a couple of things here.

First, Lazy's default implementation of length simply returns the parent's length. In this case, since an OffsetSequence will always have the same number of elements as its parent, that implementation is fine; so we don't need to override it.

Second, the default implementation of each uses get and length to essentially create a for loop, which is fine here. If you want to implement each your own way, you can do that; but in most cases (as here), you can probably just stick with the default.

So we're already done, after only implementing get! Pretty easy, huh?

Now the offset method will be chainable from any ArrayLikeSequence. So for example:

Lazy([1, 2, 3]).map(mapFn).offset(3);

...will work, but:

Lazy([1, 2, 3]).filter(mapFn).offset(3);

...will not (because filter does not return an ArrayLikeSequence).

(Also, as with the example provided for defining custom Sequence types, this example really could have been implemented using a function already available as part of Lazy.js: in this case, Sequence#map.)

Examples
Lazy([1, 2, 3])                    
Lazy([1, 2, 3]).map(Lazy.identity) 
Lazy([1, 2, 3]).take(2)            
Lazy([1, 2, 3]).drop(2)            
Lazy([1, 2, 3]).reverse()          
Lazy([1, 2, 3]).slice(1, 2)        
define ArrayLikeSequence.define

Create a new constructor function for a type inheriting from ArrayLikeSequence.

Signature
ArrayLikeSequence.define = function(methodName, overrides) {  }
ArrayLikeSequence.define = function define(methodName, overrides) {
  if (!overrides || typeof overrides.get !== 'function') {
    throw new Error("A custom array-like sequence must implement *at least* get!");
  }

  return defineSequenceType(ArrayLikeSequence, methodName, overrides);
}
Name Type(s) Description methodName string|Array.<string>

The name(s) of the method(s) to be used for constructing the new sequence. The method will be attached to the ArrayLikeSequence prototype so that it can be chained with any other methods that return array-like sequences.

overrides Object

An object containing function overrides for this new sequence type. Must include get. May include init, length, getIterator, and each. For each function, this will be the new sequence and this.parent will be the source sequence.

returns Function

A constructor for a new type inheriting from ArrayLikeSequence.

Examples
Lazy.ArrayLikeSequence.define("offset", {
  init: function(offset) {
    this.offset = offset;
  },

  get: function(i) {
    return this.parent.get((i + this.offset) % this.parent.length());
  }
});

Lazy([1, 2, 3]).offset(1) 
concat ArrayLikeSequence#concat

An optimized version of Sequence#concat that returns another ArrayLikeSequence if the argument is an array.

Signature
ArrayLikeSequence.concat = function(var_args) {  }
ArrayLikeSequence.concat = function concat(var_args) {
  if (arguments.length === 1 && isArray(arguments[0])) {
    return new IndexedConcatenatedSequence(this, ( var_args));
  } else {
    return Sequence.prototype.concat.apply(this, arguments);
  }
}
Name Type(s) Description var_args ...* Examples
Lazy([1, 2]).concat([3, 4]) 
Lazy([1, 2]).concat([3, 4]) 
first ArrayLikeSequence#first

An optimized version of Sequence#first, which creates an ArrayLikeSequence so that the result still provides random access.

Examples
Lazy([1, 2, 3]).first(2) 
get ArrayLikeSequence#get

Returns the element at the specified index.

Signature
ArrayLikeSequence.get = function(i) {  }
ArrayLikeSequence.get = function get(i) {
  return this.parent.get(i);
}
Name Type(s) Description i number

The index to access.

returns *

The element.

Examples
function increment(x) { return x + 1; }

Lazy([1, 2, 3]).get(1)                
Lazy([1, 2, 3]).get(-1)               
Lazy([1, 2, 3]).map(increment).get(1) 
length ArrayLikeSequence#length

Returns the length of the sequence.

Signature
ArrayLikeSequence.length = function() {  }
ArrayLikeSequence.length = function length() {
  return this.parent.length();
}
Name Type(s) Description returns number

The length.

Examples
function increment(x) { return x + 1; }

Lazy([]).length()                       
Lazy([1, 2, 3]).length()                
Lazy([1, 2, 3]).map(increment).length() 
map ArrayLikeSequence#map

An optimized version of Sequence#map, which creates an ArrayLikeSequence so that the result still provides random access.

Examples
Lazy([1, 2, 3]).map(Lazy.identity) 
pop ArrayLikeSequence#pop

Returns a new sequence with the same elements as this one, minus the last element.

Signature
ArrayLikeSequence.pop = function() {  }
ArrayLikeSequence.pop = function pop() {
  return this.initial();
}
Name Type(s) Description returns ArrayLikeSequence

The new array-like sequence.

Examples
Lazy([1, 2, 3]).pop() 
Lazy([]).pop()        
push ArrayLikeSequence#push

Returns a new sequence with the same elements as this one, plus the specified element at the end.

Signature
ArrayLikeSequence.push = function() {  }
ArrayLikeSequence.push = function push(value) {
  return this.concat([value]);
}
Name Type(s) Description returns ArrayLikeSequence

The new array-like sequence.

Examples
Lazy([1, 2]).push(3) 
Lazy([]).push(1)     
rest ArrayLikeSequence#rest

An optimized version of Sequence#rest, which creates an ArrayLikeSequence so that the result still provides random access.

Examples
Lazy([1, 2, 3]).rest() 
reverse ArrayLikeSequence#reverse

An optimized version of Sequence#reverse, which creates an ArrayLikeSequence so that the result still provides random access.

Examples
Lazy([1, 2, 3]).reverse() 
shift ArrayLikeSequence#shift

Returns a new sequence with the same elements as this one, minus the first element.

Signature
ArrayLikeSequence.shift = function() {  }
ArrayLikeSequence.shift = function shift() {
  return this.drop();
}
Name Type(s) Description returns ArrayLikeSequence

The new array-like sequence.

Examples
Lazy([1, 2, 3]).shift() 
Lazy([]).shift()        
slice ArrayLikeSequence#slice

Returns a new sequence comprising the portion of this sequence starting from the specified starting index and continuing until the specified ending index or to the end of the sequence.

Signature
ArrayLikeSequence.slice = function(begin, end) {  }
ArrayLikeSequence.slice = function slice(begin, end) {
  var length = this.length();

  if (begin < 0) {
    begin = length + begin;
  }

  var result = this.drop(begin);

  if (typeof end === "number") {
    if (end < 0) {
      end = length + end;
    }
    result = result.take(end - begin);
  }

  return result;
}
Name Type(s) Description begin number

The index at which the new sequence should start.

end number?

The index at which the new sequence should end.

returns ArrayLikeSequence

The new array-like sequence.

Examples
Lazy([1, 2, 3, 4, 5]).slice(0)     
Lazy([1, 2, 3, 4, 5]).slice(2)     
Lazy([1, 2, 3, 4, 5]).slice(2, 4)  
Lazy([1, 2, 3, 4, 5]).slice(-1)    
Lazy([1, 2, 3, 4, 5]).slice(1, -1) 
Lazy([1, 2, 3, 4, 5]).slice(0, 10) 
unshift ArrayLikeSequence#unshift

Returns a new sequence with the same elements as this one, plus the specified element at the beginning.

Signature
ArrayLikeSequence.unshift = function() {  }
ArrayLikeSequence.unshift = function unshift(value) {
  return Lazy([value]).concat(this);
}
Name Type(s) Description returns ArrayLikeSequence

The new array-like sequence.

Examples
Lazy([1, 2]).unshift(3) 
Lazy([]).unshift(1)     
ObjectLikeSequence ObjectLikeSequence

An ObjectLikeSequence object represents a sequence of key/value pairs.

The initial sequence you get by wrapping an object with Lazy(object) is an ObjectLikeSequence.

All methods of ObjectLikeSequence that conceptually should return something like an object return another ObjectLikeSequence.

Examples
var obj = { foo: 'bar' };

Lazy(obj).assign({ bar: 'baz' })   
Lazy(obj).defaults({ bar: 'baz' }) 
Lazy(obj).invert()                 
define ObjectLikeSequence.define

Create a new constructor function for a type inheriting from ObjectLikeSequence.

Signature
ObjectLikeSequence.define = function(methodName, overrides) {  }
ObjectLikeSequence.define = function define(methodName, overrides) {
  if (!overrides || typeof overrides.each !== 'function') {
    throw new Error("A custom object-like sequence must implement *at least* each!");
  }

  return defineSequenceType(ObjectLikeSequence, methodName, overrides);
}
Name Type(s) Description methodName string|Array.<string>

The name(s) of the method(s) to be used for constructing the new sequence. The method will be attached to the ObjectLikeSequence prototype so that it can be chained with any other methods that return object-like sequences.

overrides Object

An object containing function overrides for this new sequence type. Must include each. May include init and get (for looking up an element by key).

returns Function

A constructor for a new type inheriting from ObjectLikeSequence.

Examples
function downcaseKey(value, key) {
  return [key.toLowerCase(), value];
}

Lazy.ObjectLikeSequence.define("caseInsensitive", {
  init: function() {
    var downcased = this.parent
      .map(downcaseKey)
      .toObject();
    this.downcased = Lazy(downcased);
  },

  get: function(key) {
    return this.downcased.get(key.toLowerCase());
  },

  each: function(fn) {
    return this.downcased.each(fn);
  }
});

Lazy({ Foo: 'bar' }).caseInsensitive()            
Lazy({ FOO: 'bar' }).caseInsensitive().get('foo') 
Lazy({ FOO: 'bar' }).caseInsensitive().get('FOO') 
assign ObjectLikeSequence#assign

aliases: extend

Returns an ObjectLikeSequence whose elements are the combination of this sequence and another object. In the case of a key appearing in both this sequence and the given object, the other object's value will override the one in this sequence.

Signature
ObjectLikeSequence.assign = function(other) {  }
ObjectLikeSequence.assign = function assign(other) {
  return new AssignSequence(this, other);
}
Name Type(s) Description other Object

The other object to assign to this sequence.

returns ObjectLikeSequence

A new sequence comprising elements from this sequence plus the contents of other.

Examples
Lazy({ "uno": 1, "dos": 2 }).assign({ "tres": 3 })     
Lazy({ foo: "bar" }).assign({ foo: "baz" });           
Lazy({ foo: 'foo' }).assign({ foo: false }).get('foo') 
async ObjectLikeSequence#async

Throws an exception. Asynchronous iteration over object-like sequences is not supported.

Examples
Lazy({ foo: 'bar' }).async() 
defaults ObjectLikeSequence#defaults

Returns an ObjectLikeSequence whose elements are the combination of this sequence and a 'default' object. In the case of a key appearing in both this sequence and the given object, this sequence's value will override the default object's.

Signature
ObjectLikeSequence.defaults = function(defaults) {  }
ObjectLikeSequence.defaults = function defaults(defaults) {
  return new DefaultsSequence(this, defaults);
}
Name Type(s) Description defaults Object

The 'default' object to use for missing keys in this sequence.

returns ObjectLikeSequence

A new sequence comprising elements from this sequence supplemented by the contents of defaults.

Examples
Lazy({ name: "Dan" }).defaults({ name: "User", password: "passw0rd" }) 
Lazy({ foo: false }).defaults({ foo: 'foo' }).get('foo') 
Lazy({ a: 1 }).defaults({ b: 2 }).defaults({ c: 3 }) 
Lazy({ a: 1 }).defaults({ b: 2 }).defaults({ a: 3 }) 
Lazy({ a: 1, b: 2 }).defaults({ b: 5 }).defaults({ c: 3, d: 4 }) 
functions ObjectLikeSequence#functions

aliases: methods

Creates a Sequence consisting of the keys from this sequence whose values are functions.

Signature
ObjectLikeSequence.functions = function() {  }
ObjectLikeSequence.functions = function functions() {
  return this
    .filter(function(v, k) { return typeof(v) === "function"; })
    .map(function(v, k) { return k; });
}
Name Type(s) Description returns Sequence

The new sequence.

Examples
var dog = {
  name: "Fido",
  breed: "Golden Retriever",
  bark: function() { console.log("Woof!"); },
  wagTail: function() { console.log("TODO: implement robotic dog interface"); }
};

Lazy(dog).functions() 
get ObjectLikeSequence#get

Gets the element at the specified key in this sequence.

Signature
ObjectLikeSequence.get = function(key) {  }
ObjectLikeSequence.get = function get(key) {
  var pair = this.pairs().find(function(pair) {
    return pair[0] === key;
  });

  return pair ? pair[1] : undefined;
}
Name Type(s) Description key string

The key.

returns *

The element.

Examples
Lazy({ foo: "bar" }).get("foo")                          
Lazy({ foo: "bar" }).extend({ foo: "baz" }).get("foo")   
Lazy({ foo: "bar" }).defaults({ bar: "baz" }).get("bar") 
Lazy({ foo: "bar" }).invert().get("bar")                 
Lazy({ foo: 1, bar: 2 }).pick(["foo"]).get("foo")        
Lazy({ foo: 1, bar: 2 }).pick(["foo"]).get("bar")        
Lazy({ foo: 1, bar: 2 }).omit(["foo"]).get("bar")        
Lazy({ foo: 1, bar: 2 }).omit(["foo"]).get("foo")        
invert ObjectLikeSequence#invert

Returns an ObjectLikeSequence whose values are this sequence's keys, and whose keys are this sequence's values.

Signature
ObjectLikeSequence.invert = function() {  }
ObjectLikeSequence.invert = function invert() {
  return new InvertedSequence(this);
}
Name Type(s) Description returns ObjectLikeSequence

A new sequence comprising the inverted keys and values from this sequence.

Examples
Lazy({ first: "Dan", last: "Tao" }).invert() 
keys ObjectLikeSequence#keys

Returns a Sequence whose elements are the keys of this object-like sequence.

Signature
ObjectLikeSequence.keys = function() {  }
ObjectLikeSequence.keys = function keys() {
  return new KeySequence(this);
}
Name Type(s) Description returns Sequence

The sequence based on this sequence's keys.

Examples
var obj = { hello: "hola", goodbye: "hasta luego" };

Lazy(obj).keys() 
Lazy(obj).keys().map(function(v, i) { return [v, i]; }) 
merge ObjectLikeSequence#merge

Produces an ObjectLikeSequence consisting of all the recursively merged values from this and the given object(s) or sequence(s).

Note that by default this method only merges "vanilla" objects (bags of key/value pairs), not arrays or any other custom object types. To customize how merging works, you can provide the mergeFn argument, e.g. to handling merging arrays, strings, or other types of objects.

Signature
ObjectLikeSequence.merge = function(others, mergeFn) {  }
ObjectLikeSequence.merge = function merge(var_args) {
  var mergeFn = arguments.length > 1 && typeof arguments[arguments.length - 1] === "function" ?
    arrayPop.call(arguments) : null;
  return new MergedSequence(this, arraySlice.call(arguments, 0), mergeFn);
}
Name Type(s) Description others ...Object|ObjectLikeSequence

The other object(s) or sequence(s) whose values will be merged into this one.

mergeFn Function?

An optional function used to customize merging behavior. The function should take two values as parameters and return whatever the "merged" form of those values is. If the function returns undefined then the new value will simply replace the old one in the final result.

returns ObjectLikeSequence

The new sequence consisting of merged values.

Examples



var names = {
  'characters': [
    { 'name': 'barney' },
    { 'name': 'fred' }
  ]
};

var ages = {
  'characters': [
    { 'age': 36 },
    { 'age': 40 }
  ]
};

var food = {
  'fruits': ['apple'],
  'vegetables': ['beet']
};

var otherFood = {
  'fruits': ['banana'],
  'vegetables': ['carrot']
};

function mergeArrays(a, b) {
  return Array.isArray(a) ? a.concat(b) : undefined;
}

Lazy(names).merge(ages); 
Lazy(food).merge(otherFood, mergeArrays); 




Lazy({ foo: 1 }).merge({ foo: 2 }); 
Lazy({ foo: 1 }).merge({ bar: 2 }); 


Lazy({ foo: { bar: 1 } }).merge({ foo: { bar: 2 } }); 
Lazy({ foo: { bar: 1 } }).merge({ foo: { baz: 2 } }); 
Lazy({ foo: { bar: 1 } }).merge({ foo: { baz: 2 } }); 


Lazy({ foo: 1 }).merge({ bar: 2 }, { bar: 3 }); 


Lazy({ foo: 1 }).merge({ foo: undefined }); 


Lazy({ foo: 1 }).merge({ foo: null }); 


Lazy({ foo: [{ bar: 1 }] }).merge({ foo: [{ baz: 2 }] }); 
omit ObjectLikeSequence#omit

Creates an ObjectLikeSequence consisting of the key/value pairs from this sequence excluding those with the specified keys. Non-string keys are effectively ignored.

Signature
ObjectLikeSequence.omit = function(properties) {  }
ObjectLikeSequence.omit = function omit(properties) {
  return new OmitSequence(this, properties);
}
Name Type(s) Description properties Array

An array of the properties to omit from this sequence.

returns ObjectLikeSequence

The new sequence.

Examples
var players = {
  "who": "first",
  "what": "second",
  "i don't know": "third"
};

Lazy(players).omit(["who", "what"]) 


Lazy({1: 2, true: false}).omit([1, true]) 
pairs ObjectLikeSequence#pairs

aliases: toArray

Maps the key/value pairs in this sequence to arrays.

Signature
ObjectLikeSequence.pairs = function() {  }
ObjectLikeSequence.pairs = function pairs() {
  return this.map(function(v, k) { return [k, v]; });
}
Name Type(s) Description returns Sequence

An sequence of [key, value] pairs.

Examples
var colorCodes = {
  red: "#f00",
  green: "#0f0",
  blue: "#00f"
};

Lazy(colorCodes).pairs() 
pick ObjectLikeSequence#pick

Creates an ObjectLikeSequence consisting of the key/value pairs from this sequence whose keys are included in the given array of property names.

Signature
ObjectLikeSequence.pick = function(properties) {  }
ObjectLikeSequence.pick = function pick(properties) {
  return new PickSequence(this, properties);
}
Name Type(s) Description properties Array.<string>

An array of the properties to "pick" from this sequence.

returns ObjectLikeSequence

The new sequence.

Examples
var players = {
  "who": "first",
  "what": "second",
  "i don't know": "third"
};

Lazy(players).pick(["who", "what"]) 
toArray ObjectLikeSequence#toArray

Creates an array from the key/value pairs in this sequence.

Signature
ObjectLikeSequence.toArray = function() {  }
ObjectLikeSequence.toArray = function toArray() {
  return this.pairs().toArray();
}
Name Type(s) Description returns Array

An array of [key, value] elements.

Examples
var colorCodes = {
  red: "#f00",
  green: "#0f0",
  blue: "#00f"
};

Lazy(colorCodes).toArray() 
toObject ObjectLikeSequence#toObject

Creates an object with the key/value pairs from this sequence.

Signature
ObjectLikeSequence.toObject = function() {  }
ObjectLikeSequence.toObject = function toObject() {
  return this.reduce(function(object, value, key) {
    object[key] = value;
    return object;
  }, {});
}
Name Type(s) Description returns Object

An object with the same key/value pairs as this sequence.

Examples
var colorCodes = {
  red: "#f00",
  green: "#0f0",
  blue: "#00f"
};

Lazy(colorCodes).toObject() 
values ObjectLikeSequence#values

Returns a Sequence whose elements are the values of this object-like sequence.

Signature
ObjectLikeSequence.values = function() {  }
ObjectLikeSequence.values = function values() {
  return new ValuesSequence(this);
}
Name Type(s) Description returns Sequence

The sequence based on this sequence's values.

Examples
Lazy({ hello: "hola", goodbye: "hasta luego" }).values() 
watch ObjectLikeSequence#watch

Watches for all changes to a specified property (or properties) of an object and produces a sequence whose elements have the properties { property, value } indicating which property changed and what it was changed to.

Note that this method only works on directly wrapped objects; it will not work on any arbitrary ObjectLikeSequence.

Signature
ObjectLikeSequence.watch = function(propertyNames) {  }
ObjectLikeSequence.watch = function watch(propertyNames) {
  throw new Error('You can only call #watch on a directly wrapped object.');
}
Name Type(s) Description propertyNames string|Array?

A property name or array of property names to watch. If this parameter is undefined, all of the object's current (enumerable) properties will be watched.

returns Sequence

A sequence comprising { property, value } objects describing each change to the specified property/properties.

Examples
var obj = {},
    changes = [];

Lazy(obj).watch('foo').each(function(change) {
  changes.push(change);
});

obj.foo = 1;
obj.bar = 2;
obj.foo = 3;

obj.foo; 
changes; 
StringLikeSequence StringLikeSequence

A StringLikeSequence represents a sequence of characters.

The initial sequence you get by wrapping a string with Lazy(string) is a StringLikeSequence.

All methods of StringLikeSequence that conceptually should return something like a string return another StringLikeSequence.

Examples
function upcase(str) { return str.toUpperCase(); }

Lazy('foo')               
Lazy('foo').toUpperCase() 
Lazy('foo').reverse()     
Lazy('foo').take(2)       
Lazy('foo').drop(1)       
Lazy('foo').substring(1)  





Lazy('foo').map(Lazy.identity)       
Lazy('foo').mapString(Lazy.identity) 
define StringLikeSequence.define

Create a new constructor function for a type inheriting from StringLikeSequence.

Signature
StringLikeSequence.define = function(methodName, overrides) {  }
StringLikeSequence.define = function define(methodName, overrides) {
  if (!overrides || typeof overrides.get !== 'function') {
    throw new Error("A custom string-like sequence must implement *at least* get!");
  }

  return defineSequenceType(StringLikeSequence, methodName, overrides);
}
Name Type(s) Description methodName string|Array.<string>

The name(s) of the method(s) to be used for constructing the new sequence. The method will be attached to the StringLikeSequence prototype so that it can be chained with any other methods that return string-like sequences.

overrides Object

An object containing function overrides for this new sequence type. Has the same requirements as ArrayLikeSequence.define.

returns Function

A constructor for a new type inheriting from StringLikeSequence.

Examples
Lazy.StringLikeSequence.define("zomg", {
  length: function() {
    return this.parent.length() + "!!ZOMG!!!1".length;
  },

  get: function(i) {
    if (i < this.parent.length()) {
      return this.parent.get(i);
    }
    return "!!ZOMG!!!1".charAt(i - this.parent.length());
  }
});

Lazy('foo').zomg() 
charAt StringLikeSequence#charAt

Returns the character at the given index of this sequence, or the empty string if the specified index lies outside the bounds of the sequence.

Signature
StringLikeSequence.charAt = function(i) {  }
StringLikeSequence.charAt = function charAt(i) {
  return this.get(i);
}
Name Type(s) Description i number

The index of this sequence.

returns string

The character at the specified index.

Examples
Lazy("foo").charAt(0)  
Lazy("foo").charAt(-1) 
Lazy("foo").charAt(10) 
charCodeAt StringLikeSequence#charCodeAt

Returns the character code at the given index of this sequence, or NaN if the index lies outside the bounds of the sequence.

Signature
StringLikeSequence.charCodeAt = function(i) {  }
StringLikeSequence.charCodeAt = function charCodeAt(i) {
  var char = this.charAt(i);
  if (!char) { return NaN; }

  return char.charCodeAt(0);
}
Name Type(s) Description i number

The index of the character whose character code you want.

returns number

The character code.

Examples
Lazy("abc").charCodeAt(0)  
Lazy("abc").charCodeAt(-1) 
Lazy("abc").charCodeAt(10) 
contains StringLikeSequence#contains

Checks if this sequence contains a given substring.

Signature
StringLikeSequence.contains = function(substring) {  }
StringLikeSequence.contains = function contains(substring) {
  return this.indexOf(substring) !== -1;
}
Name Type(s) Description substring string

The substring to check for.

returns boolean

Whether or not this sequence contains substring.

Examples
Lazy('hello').contains('ell') 
Lazy('hello').contains('')    
Lazy('hello').contains('abc') 
endsWith StringLikeSequence#endsWith

Checks if this sequence ends with a given suffix.

Signature
StringLikeSequence.endsWith = function(suffix) {  }
StringLikeSequence.endsWith = function endsWith(suffix) {
  return this.substring(this.length() - suffix.length).toString() === suffix;
}
Name Type(s) Description suffix string

The suffix to check for.

returns boolean

Whether or not this sequence ends with suffix.

Examples
Lazy('foo').endsWith('oo')  
Lazy('foo').endsWith('')    
Lazy('foo').endsWith('abc') 
first StringLikeSequence#first

An optimized version of Sequence#first that returns another StringLikeSequence (or just the first character, if count is undefined).

Examples
Lazy('foo').first()                
Lazy('fo').first(2)                
Lazy('foo').first(10)              
Lazy('foo').toUpperCase().first()  
Lazy('foo').toUpperCase().first(2) 
indexOf StringLikeSequence#indexOf

Finds the index of the first occurrence of the given substring within this sequence, starting from the specified index (or the beginning of the sequence).

Signature
StringLikeSequence.indexOf = function(substring, startIndex) {  }
StringLikeSequence.indexOf = function indexOf(substring, startIndex) {
  return this.toString().indexOf(substring, startIndex);
}
Name Type(s) Description substring string

The substring to search for.

startIndex number?

The index from which to start the search.

returns number

The first index where the given substring is found, or -1 if it isn't in the sequence.

Examples
Lazy('canal').indexOf('a')    
Lazy('canal').indexOf('a', 2) 
Lazy('canal').indexOf('ana')  
Lazy('canal').indexOf('andy') 
Lazy('canal').indexOf('x')    
last StringLikeSequence#last

An optimized version of Sequence#last that returns another StringLikeSequence (or just the last character, if count is undefined).

Examples
Lazy('foo').last()                
Lazy('foo').last(2)               
Lazy('foo').last(10)              
Lazy('foo').toUpperCase().last()  
Lazy('foo').toUpperCase().last(2) 
lastIndexOf StringLikeSequence#lastIndexOf

Finds the index of the last occurrence of the given substring within this sequence, starting from the specified index (or the end of the sequence) and working backwards.

Signature
StringLikeSequence.lastIndexOf = function(substring, startIndex) {  }
StringLikeSequence.lastIndexOf = function lastIndexOf(substring, startIndex) {
  return this.toString().lastIndexOf(substring, startIndex);
}
Name Type(s) Description substring string

The substring to search for.

startIndex number?

The index from which to start the search.

returns number

The last index where the given substring is found, or -1 if it isn't in the sequence.

Examples
Lazy('canal').lastIndexOf('a')    
Lazy('canal').lastIndexOf('a', 2) 
Lazy('canal').lastIndexOf('ana')  
Lazy('canal').lastIndexOf('andy') 
Lazy('canal').lastIndexOf('x')    
mapString StringLikeSequence#mapString

Maps the characters of this sequence onto a new StringLikeSequence.

Signature
StringLikeSequence.mapString = function(mapFn) {  }
StringLikeSequence.mapString = function mapString(mapFn) {
  return new MappedStringLikeSequence(this, mapFn);
}
Name Type(s) Description mapFn Function

The function used to map characters from this sequence onto the new sequence.

returns StringLikeSequence

The new sequence.

Examples
function upcase(char) { return char.toUpperCase(); }

Lazy("foo").mapString(upcase)               
Lazy("foo").mapString(upcase).charAt(0)     
Lazy("foo").mapString(upcase).charCodeAt(0) 
Lazy("foo").mapString(upcase).substring(1)  
match StringLikeSequence#match

Creates a Sequence comprising all of the matches for the specified pattern in the underlying string.

Signature
StringLikeSequence.match = function(pattern) {  }
StringLikeSequence.match = function match(pattern) {
  return new StringMatchSequence(this, pattern);
}
Name Type(s) Description pattern RegExp

The pattern to match.

returns Sequence

A sequence of all the matches.

Examples
Lazy("abracadabra").match(/a[bcd]/) 
Lazy("fee fi fo fum").match(/\w+/)  
Lazy("hello").match(/xyz/)          
reverse StringLikeSequence#reverse

Returns a copy of this sequence that reads back to front.

Examples
Lazy("abcdefg").reverse() 
split StringLikeSequence#split

Creates a Sequence comprising all of the substrings of this string separated by the given delimiter, which can be either a string or a regular expression.

Signature
StringLikeSequence.split = function(delimiter) {  }
StringLikeSequence.split = function split(delimiter) {
  return new SplitStringSequence(this, delimiter);
}
Name Type(s) Description delimiter string|RegExp

The delimiter to use for recognizing substrings.

returns Sequence

A sequence of all the substrings separated by the given delimiter.

Examples
Lazy("foo").split("")                      
Lazy("yo dawg").split(" ")                 
Lazy("bah bah\tblack  sheep").split(/\s+/) 
startsWith StringLikeSequence#startsWith

Checks if this sequence starts with a given prefix.

Signature
StringLikeSequence.startsWith = function(prefix) {  }
StringLikeSequence.startsWith = function startsWith(prefix) {
  return this.substring(0, prefix.length).toString() === prefix;
}
Name Type(s) Description prefix string

The prefix to check for.

returns boolean

Whether or not this sequence starts with prefix.

Examples
Lazy('foo').startsWith('fo')  
Lazy('foo').startsWith('')    
Lazy('foo').startsWith('abc') 
substring StringLikeSequence#substring

Returns a StringLikeSequence comprising the characters from this sequence starting at start and ending at stop (exclusive), or---if stop is undefined, including the rest of the sequence.

Signature
StringLikeSequence.substring = function(start, stop) {  }
StringLikeSequence.substring = function substring(start, stop) {
  return new StringSegment(this, start, stop);
}
Name Type(s) Description start number

The index where this sequence should begin.

stop number?

The index (exclusive) where this sequence should end.

returns StringLikeSequence

The new sequence.

Examples
Lazy("foo").substring(1)      
Lazy("foo").substring(-1)     
Lazy("hello").substring(1, 3) 
Lazy("hello").substring(1, 9) 
Lazy("foo").substring(0, 0)   
Lazy("foo").substring(3, 3)   
toLowerCase StringLikeSequence#toLowerCase

Converts all of the characters in this string to lowercase.

Signature
StringLikeSequence.toLowerCase = function() {  }
StringLikeSequence.toLowerCase = function toLowerCase() {
  return this.mapString(function(char) { return char.toLowerCase(); });
}
Name Type(s) Description returns StringLikeSequence

A new sequence with the same characters as this sequence, all lowercase.

Examples
function nextLetter(a) {
  return String.fromCharCode(a.charCodeAt(0) + 1);
}

Lazy('FOO').toLowerCase()                       
Lazy('FOO').substring(1).toLowerCase()          
Lazy('ABC').mapString(nextLetter).toLowerCase() 
toUpperCase StringLikeSequence#toUpperCase

Converts all of the characters in this string to uppercase.

Signature
StringLikeSequence.toUpperCase = function() {  }
StringLikeSequence.toUpperCase = function toUpperCase() {
  return this.mapString(function(char) { return char.toUpperCase(); });
}
Name Type(s) Description returns StringLikeSequence

A new sequence with the same characters as this sequence, all uppercase.

Examples
function nextLetter(a) {
  return String.fromCharCode(a.charCodeAt(0) + 1);
}

Lazy('foo').toUpperCase()                       
Lazy('foo').substring(1).toUpperCase()          
Lazy('abc').mapString(nextLetter).toUpperCase() 
GeneratedSequence GeneratedSequence

A GeneratedSequence does not wrap an in-memory collection but rather determines its elements on-the-fly during iteration according to a generator function.

You create a GeneratedSequence by calling Lazy.generate.

Signature
function GeneratedSequence(generatorFn, length) {  }
function GeneratedSequence(generatorFn, length) {
  this.get = generatorFn;
  this.fixedLength = length;
}
Name Type(s) Description generatorFn function(number):*

A function which accepts an index and returns a value for the element at that position in the sequence.

length number?

The length of the sequence. If this argument is omitted, the sequence will go on forever.

each GeneratedSequence#each

Iterates over the sequence produced by invoking this sequence's generator function up to its specified length, or, if length is undefined, indefinitely (in which case the sequence will go on forever--you would need to call, e.g., Sequence#take to limit iteration).

Signature
GeneratedSequence.each = function(fn) {  }
GeneratedSequence.each = function each(fn) {
  var generatorFn = this.get,
      length = this.fixedLength,
      i = 0;

  while (typeof length === "undefined" || i < length) {
    if (fn(generatorFn(i), i++) === false) {
      return false;
    }
  }

  return true;
}
Name Type(s) Description fn Function

The function to call on each output from the generator function.

length GeneratedSequence#length

Returns the length of this sequence.

Signature
GeneratedSequence.length = function() {  }
GeneratedSequence.length = function length() {
  return this.fixedLength;
}
Name Type(s) Description returns number

The length, or undefined if this is an indefinite sequence.

AsyncSequence AsyncSequence

An AsyncSequence iterates over its elements asynchronously when #each is called.

You get an AsyncSequence by calling Sequence#async on any sequence. Note that some sequence types may not support asynchronous iteration.

Returning values

Because of its asynchronous nature, an AsyncSequence cannot be used in the same way as other sequences for functions that return values directly (e.g., reduce, max, any, even toArray).

Instead, these methods return an AsyncHandle whose onComplete method accepts a callback that will be called with the final result once iteration has finished.

Defining custom asynchronous sequences

There are plenty of ways to define an asynchronous sequence. Here's one.

  1. First, implement an Iterator. This is an object whose prototype has the methods Iterator#moveNext (which returns a boolean) and current (which returns the current value).
  2. Next, create a simple wrapper that inherits from AsyncSequence, whose getIterator function returns an instance of the iterator type you just defined.

The default implementation for #each on an AsyncSequence is to create an iterator and then asynchronously call Iterator#moveNext (using setImmediate, if available, otherwise setTimeout) until the iterator can't move ahead any more.

Signature
function AsyncSequence(parent, interval) {  }
function AsyncSequence(parent, interval) {
  if (parent instanceof AsyncSequence) {
    throw new Error("Sequence is already asynchronous!");
  }

  this.parent         = parent;
  this.interval       = interval;
  this.onNextCallback = getOnNextCallback(interval);
  this.cancelCallback = getCancelCallback(interval);
}
Name Type(s) Description parent Sequence

A Sequence to wrap, to expose asynchronous iteration.

interval number?

How many milliseconds should elapse between each element when iterating over this sequence. Note that this interval applies even to the first value in the sequence; i.e., when calling each(), this much time will elapse before the first element is iterated.

If this argument is omitted, asynchronous iteration will be executed
as fast as possible.
contains AsyncSequence#contains

A version of Sequence#contains which returns an AsyncHandle.

Signature
AsyncSequence.contains = function(value) {  }
AsyncSequence.contains = function contains(value) {
  var found = false;

  var handle = this.each(function(e) {
    if (e === value) {
      found = true;
      return false;
    }
  });

  return handle.then(function() {
    return found;
  });
}
Name Type(s) Description value *

The element to search for in the sequence.

returns AsyncHandle

An AsyncHandle (promise) which resolves to either true or false to indicate whether the element was found.

each AsyncSequence#each

An asynchronous version of Sequence#each.

Signature
AsyncSequence.each = function(fn) {  }
AsyncSequence.each = function each(fn) {
  var iterator = this.parent.getIterator(),
      onNextCallback = this.onNextCallback,
      cancelCallback = this.cancelCallback,
      i = 0;

  var handle = new AsyncHandle(function cancel() {
    if (cancellationId) {
      cancelCallback(cancellationId);
    }
  });

  var cancellationId = onNextCallback(function iterate() {
    cancellationId = null;

    try {
      if (iterator.moveNext() && fn(iterator.current(), i++) !== false) {
        cancellationId = onNextCallback(iterate);

      } else {
        handle._resolve();
      }

    } catch (e) {
      handle._reject(e);
    }
  });

  return handle;
}
Name Type(s) Description fn Function

The function to invoke asynchronously on each element in the sequence one by one.

returns AsyncHandle

An AsyncHandle providing the ability to cancel the asynchronous iteration (by calling cancel()) as well as supply callback(s) for when an error is encountered (onError) or when iteration is complete (onComplete).

find AsyncSequence#find

A version of Sequence#find which returns an AsyncHandle.

Signature
AsyncSequence.find = function(predicate) {  }
AsyncSequence.find = function find(predicate) {
  var found;

  var handle = this.each(function(e, i) {
    if (predicate(e, i)) {
      found = e;
      return false;
    }
  });

  return handle.then(function() { return found; });
}
Name Type(s) Description predicate Function

A function to call on (potentially) every element in the sequence.

returns AsyncHandle

An AsyncHandle (promise) which resolves to the found element, once it is detected, or else undefined.

getIterator AsyncSequence#getIterator

Throws an exception. You cannot manually iterate over an asynchronous sequence.

Examples
Lazy([1, 2, 3]).async().getIterator() 
indexOf AsyncSequence#indexOf

A version of Sequence#indexOf which returns an AsyncHandle.

Signature
AsyncSequence.indexOf = function(value) {  }
AsyncSequence.indexOf = function indexOf(value) {
  var foundIndex = -1;

  var handle = this.each(function(e, i) {
    if (e === value) {
      foundIndex = i;
      return false;
    }
  });

  return handle.then(function() {
    return foundIndex;
  });
}
Name Type(s) Description value *

The element to search for in the sequence.

returns AsyncHandle

An AsyncHandle (promise) which resolves to the found index, once it is detected, or -1.

Iterator Iterator

The Iterator object provides an API for iterating over a sequence.

The purpose of the Iterator type is mainly to offer an agnostic way of iterating over a sequence -- either synchronous (i.e. with a while loop) or asynchronously (with recursive calls to either setTimeout or --- if available --- setImmediate). It is not intended to be used directly by application code.

Signature
function Iterator(sequence) {  }
function Iterator(sequence) {
  this.sequence = sequence;
  this.index    = -1;
}
Name Type(s) Description sequence Sequence

The sequence to iterate over.

current Iterator#current

Gets the current item this iterator is pointing to.

Signature
Iterator.current = function() {  }
Iterator.current = function current() {
  return this.cachedIndex && this.cachedIndex.get(this.index);
}
Name Type(s) Description returns *

The current item.

moveNext Iterator#moveNext

Moves the iterator to the next item in a sequence, if possible.

Signature
Iterator.moveNext = function() {  }
Iterator.moveNext = function moveNext() {
  var cachedIndex = this.cachedIndex;

  if (!cachedIndex) {
    cachedIndex = this.cachedIndex = this.sequence.getIndex();
  }

  if (this.index >= cachedIndex.length() - 1) {
    return false;
  }

  ++this.index;
  return true;
}
Name Type(s) Description returns boolean

True if the iterator is able to move to a new item, or else false.

AsyncHandle AsyncHandle

An AsyncHandle provides a Promises/A+ compliant interface for an AsyncSequence that is currently (or was) iterating over its elements.

In addition to behaving as a promise, an AsyncHandle provides the ability to AsyncHandle#cancel iteration (if cancelFn is provided) and also offers convenient AsyncHandle#onComplete and AsyncHandle#onError methods to attach listeners for when iteration is complete or an error is thrown during iteration.

Signature
function AsyncHandle(cancelFn) {  }
function AsyncHandle(cancelFn) {
  this.resolveListeners = [];
  this.rejectListeners = [];
  this.state = PENDING;
  this.cancelFn = cancelFn;
}
Name Type(s) Description cancelFn Function

A function to cancel asynchronous iteration. This is passed in to support different cancellation mechanisms for different forms of asynchronous sequences (e.g., timeout-based sequences, sequences based on I/O, etc.).

Examples

var sequence = Lazy.generate(Math.random)
  .chunk(100)
  .async()
  .take(1000);



var handle = sequence.toArray();

handle.onComplete(function(array) {
  
});




var flattened = handle.then(function(array) {
  return Lazy(array).flatten();
});
cancel AsyncHandle#cancel

Cancels asynchronous iteration.

onComplete AsyncHandle#onComplete

Updates the handle with a callback to execute when iteration is completed.

Signature
AsyncHandle.onComplete = function(callback) {  }
AsyncHandle.onComplete = function onComplete(callback) {
  this.resolveListeners.push(callback);
  return this;
}
Name Type(s) Description callback Function

The function to call when the asynchronous iteration is completed.

onError AsyncHandle#onError

Updates the handle with a callback to execute if/when any error is encountered during asynchronous iteration.

Signature
AsyncHandle.onError = function(callback) {  }
AsyncHandle.onError = function onError(callback) {
  this.rejectListeners.push(callback);
  return this;
}
Name Type(s) Description callback Function

The function to call, with any associated error object, when an error occurs.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4