Skip to content

迭代器辅助方法

🕒 Published at:

本篇文章来源于 v8.dev, 原文链接: https://v8.dev/features/iterator-helpers, 作者: Rezvan Mahdavi Hezaveh

迭代器辅助方法(Iterator helpers) 是迭代器原型上的新方法集合,旨在帮助迭代器的通用使用。自迭代器原型上存在这些辅助方法开始,任何在其原型链上有 Iterator.prototype 的对象(如:数组迭代器)都会获得这些方法。 在下面的子章节,我们将解释这些迭代器辅助方法。所有提供的示例都在博客存档页面中工作,该页面包含博客文章列表,说明了迭代器辅助方法如何有助于查找和处理帖子。你可以在 V8 博客页面 中进行尝试。

.map(mapperFn)

map 接收一个 mapper 函数作为参数。此辅助方法返回值的迭代器,其中 mapper 函数作用于原始迭代器值。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Get the list of posts, return a list of their text content (titles) and log them.
for (const post of posts.values().map((x) => x.textContent)) {
  console.log(post);
}

.filter(filterFn)

filter 接收一个 filter 函数作为参数。此辅助方法返回值的迭代器,其中 filter 函数返回判断为真的原始迭代器值。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Filter blog posts that includes `V8` in their text content (titles) and log them.
for (const post of posts.values().filter((x) => x.textContent.includes('V8'))) {
  console.log(post);
}

.take(limit)

take 接收一个整型作为参数。此辅助方法从原始迭代器返回一个值的迭代器,最多为 limit 个。

javascript
// Select the list of blog posts from a blog archive page.
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Filter blog posts that includes `V8` in their text content (titles) and log them.
for (const post of posts.values().filter((x) => x.textContent.includes('V8'))) {
  console.log(post);
}

.drop(limit)

drop 接收一个整型作为参数。此辅助方法从原始迭代器返回一个值的迭代器,跳过 limit 个值。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Drop 10 recent blog posts and log the rest of them.
for (const post of posts.values().drop(10)) {
  console.log(post);
}

.flatMap(mapperFn)

flatMap 接收一个 mapper 函数作为参数。此辅助方法返回一个通过有原始迭代器值调用 mapper 函数返回值的迭代器。如此,通过这个辅助方法返回一个由 mapper 函数展开的迭代器。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Get list of tags of the blog posts and log them. Each post can have more than
// one tag.
for (const tag of posts.values().flatMap((x) => x.querySelectorAll('.tag').values())) {
    console.log(tag.textContent);
}

.reduce(reducer[, initialValue])

reduce 接收一个 reducer 函数和一个可选的初始值。此辅助方法返回一个值作为迭代器每个值调用 reducer 函数的结果,同时追踪 reducer 函数的最后一个结果。初始值被用于 reducer 函数的起点,当它进行处理的时候,其为迭代器的第一个值。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Get list of tags for all posts.
const tagLists = posts.values().flatMap((x) => x.querySelectorAll('.tag').values());

// Get text context for each tag in the list.
const tags = tagLists.map((x) => x.textContent);

// Counts posts with security tag.
const count = tags.reduce((sum , value) => sum + (value === 'security' ? 1 : 0), 0);
console.log(count);

.toArray()

toArray 从迭代器返回一个数组。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Create an array from the list of 10 recent blog posts.
const arr = posts.values().take(10).toArray();

.forEach(fn)

forEach 接收一个函数作为参数,并在迭代器每个元素上进行调用。这个辅助方法作为它的副作用进行调用并且返回 undefined

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Get the dates that at least one blog post is published and log them.
const dates = new Set();
const forEach = posts.values().forEach((x) => dates.add(x.querySelector('time')));
console.log(dates);

.some(fn)

some 接收一个判断函数(predicate function) 作为参数。这个辅助方法当某些迭代器元素调用判断函数返回为真的时候,返回 true。这个迭代器在 some 被调用之后被消费。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Find out if text content (title) of any blog post includes the `Iterators`
// keyword.
posts.values().some((x) => x.textContent.includes('Iterators'));

.every(fn)

every 接收一个判断函数作为参数。这个辅助方法当所有迭代器元素调用判断函数返回为真的时候,返回 true。这个迭代器在 every 被调用之后被消费。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Find out if text content (title) of all blog post includes the `V8` keyword.
posts.values().every((x) => x.textContent.includes('V8'));

.find(fn)

find 接收一个判断函数(predicate function) 作为参数。此辅助方法返回满足判断函数的迭代器的第一个值,或者返回 undefined(如果迭代器没有值)。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// Log the text content (title) of the recent blog post includes `V8` keyword.
console.log(posts.values().find((x) => x.textContent.includes('V8')).textContent);

Iterator.from(object)

from 是一个静态方法,并接收一个对象作为参数。如果 object 已经是一个迭代器的实例,被这个辅助方法直接返回。如果 objectSymbol.iterator,也就意味着是一个可迭代的对象,它的 Symbol.iterator 方法将会被此辅助函数调用并返回。此外,一个新的 Iterator 对象(继承于 Iterator.prototype,并且有 next()return() 方法)被创建包裹为 object,被此辅助方法返回。

javascript
// Select the list of blog posts from a blog archive page.
const posts = document.querySelectorAll('li:not(header li)');

// First create an iterator from the posts. Then, log the text content (title) of 
// the recent blog post that includes the `V8` keyword.
console.log(Iterator.from(posts).find((x) => x.textContent.includes('V8')).textContent);

可用性

迭代器辅助方法在 V8 v12.2 版本推出。

支持情况