返回介绍

ArrayLikeSequence

发布于 2019-05-31 13:13:03 字数 4117 浏览 895 评论 0 收藏 0

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文