ES6 使用 for..of 反向迭代数组,我是否遗漏了规范中的内容?
ES6 reverse iterate an array using for..of, have I missed something in the spec?
在 ES6 中我们现在有 iterators and for..of to iterate them. we have some built-ins for arrays; notably keys, values and entries。
这些方法允许执行通常执行的大部分迭代。但是,反向迭代呢?这也是一项非常常见的任务,我在 spec 中没有看到任何专门针对它的内容?或者我错过了?
好的,我们有 Array.prototype.reverse but I don't necessarily want to reverse a large array in place and then reverse it again when finished. I also don't want to use Array.prototype.slice 来制作一个临时的浅拷贝并反转它只是为了迭代。
所以我看了一下 generators 并提出了这些可行的解决方案。
(function() {
'use strict';
function* reverseKeys(arr) {
let key = arr.length - 1;
while (key >= 0) {
yield key;
key -= 1;
}
}
function* reverseValues(arr) {
for (let key of reverseKeys(arr)) {
yield arr[key];
}
}
function* reverseEntries(arr) {
for (let key of reverseKeys(arr)) {
yield [key, arr[key]];
}
}
var pre = document.getElementById('out');
function log(result) {
pre.appendChild(document.createTextNode(result + '\n'));
}
var a = ['a', 'b', 'c'];
for (var x of reverseKeys(a)) {
log(x);
}
log('');
for (var x of reverseValues(a)) {
log(x);
}
log('');
for (var x of reverseEntries(a)) {
log(x);
}
}());
<pre id="out"></pre>
这真的是 ES6 中反向迭代的方式吗,还是我错过了规范中的一些基本内容?
Is this really the way that reverse iteration is intended in ES6?
esdicuss and a git project outlining a spec 上讨论了反向迭代的提议,但似乎没有什么关于它的事情发生。 ES6 现在已经完成,所以这次不会添加它。无论如何,对于数组和字符串,我已经编写了一些代码来填补空白(在我看来),我将在此处 post 它,因为它可能会对其他人有所帮助。这段代码基于我今天的浏览器,如果在它们上实现了更多的 ES6,则可能会做出一些改进。稍后我可能会找到一个要点或一个小的 github 项目。
更新:我已经创建了一个 GitHub 项目来处理这个问题。
看看https://www.npmjs.com/package/itiriri。
它是一个库,具有与数组类似的方法,但可以使用迭代器。
import { query } from 'itiriri';
const m = new Map();
m.set(1, 'a');
m.set(2, 'b');
m.set(3, 'c');
const result = query(m);
for (const [k, v] of result.reverse()) {
console.log(k + ' - ' + v)
}
query
returns 具有与数组相似方法的可迭代对象。在上面的示例中,使用了 reverse()
。还有fitler
、slice
、map
、concat
等
如果您需要从查询返回数组或映射,您可以使用 .toArray()
、.toMap()
或 .toSet()
方法之一。
在 ES6 中我们现在有 iterators and for..of to iterate them. we have some built-ins for arrays; notably keys, values and entries。
这些方法允许执行通常执行的大部分迭代。但是,反向迭代呢?这也是一项非常常见的任务,我在 spec 中没有看到任何专门针对它的内容?或者我错过了?
好的,我们有 Array.prototype.reverse but I don't necessarily want to reverse a large array in place and then reverse it again when finished. I also don't want to use Array.prototype.slice 来制作一个临时的浅拷贝并反转它只是为了迭代。
所以我看了一下 generators 并提出了这些可行的解决方案。
(function() {
'use strict';
function* reverseKeys(arr) {
let key = arr.length - 1;
while (key >= 0) {
yield key;
key -= 1;
}
}
function* reverseValues(arr) {
for (let key of reverseKeys(arr)) {
yield arr[key];
}
}
function* reverseEntries(arr) {
for (let key of reverseKeys(arr)) {
yield [key, arr[key]];
}
}
var pre = document.getElementById('out');
function log(result) {
pre.appendChild(document.createTextNode(result + '\n'));
}
var a = ['a', 'b', 'c'];
for (var x of reverseKeys(a)) {
log(x);
}
log('');
for (var x of reverseValues(a)) {
log(x);
}
log('');
for (var x of reverseEntries(a)) {
log(x);
}
}());
<pre id="out"></pre>
这真的是 ES6 中反向迭代的方式吗,还是我错过了规范中的一些基本内容?
Is this really the way that reverse iteration is intended in ES6?
esdicuss and a git project outlining a spec 上讨论了反向迭代的提议,但似乎没有什么关于它的事情发生。 ES6 现在已经完成,所以这次不会添加它。无论如何,对于数组和字符串,我已经编写了一些代码来填补空白(在我看来),我将在此处 post 它,因为它可能会对其他人有所帮助。这段代码基于我今天的浏览器,如果在它们上实现了更多的 ES6,则可能会做出一些改进。稍后我可能会找到一个要点或一个小的 github 项目。
更新:我已经创建了一个 GitHub 项目来处理这个问题。
看看https://www.npmjs.com/package/itiriri。
它是一个库,具有与数组类似的方法,但可以使用迭代器。
import { query } from 'itiriri';
const m = new Map();
m.set(1, 'a');
m.set(2, 'b');
m.set(3, 'c');
const result = query(m);
for (const [k, v] of result.reverse()) {
console.log(k + ' - ' + v)
}
query
returns 具有与数组相似方法的可迭代对象。在上面的示例中,使用了 reverse()
。还有fitler
、slice
、map
、concat
等
如果您需要从查询返回数组或映射,您可以使用 .toArray()
、.toMap()
或 .toSet()
方法之一。