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()。还有fitlerslicemapconcat

如果您需要从查询返回数组或映射,您可以使用 .toArray().toMap().toSet() 方法之一。