当前位置: 首页 > 文档资料 > Lazy.js 英文文档 >

ArrayLikeSequence

优质
小牛编辑
138浏览
2023-12-01

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:

  • Sequence#map
  • ArrayLikeSequence#slice
  • Sequence#take and Sequence#drop
  • Sequence#reverse

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:

  • Sequence#filter
  • Sequence#uniq
  • Sequence#union
  • Sequence#intersect

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])                    // instanceof Lazy.ArrayLikeSequence
Lazy([1, 2, 3]).map(Lazy.identity) // instanceof Lazy.ArrayLikeSequence
Lazy([1, 2, 3]).take(2)            // instanceof Lazy.ArrayLikeSequence
Lazy([1, 2, 3]).drop(2)            // instanceof Lazy.ArrayLikeSequence
Lazy([1, 2, 3]).reverse()          // instanceof Lazy.ArrayLikeSequence
Lazy([1, 2, 3]).slice(1, 2)        // instanceof Lazy.ArrayLikeSequence