在 node.js 中为数组创建自定义迭代器有什么意义吗?

Zac*_*ith 5 javascript iterator

我需要解析一个 80GB+ 的 CSV 文件,并认为这是一个很好的机会来理解 JavaScript 中的迭代器(然后可能使用现有的库,如csv-iteratorfast-csv等)。

查看 MDN HERE上的迭代器示例,我看到以下代码:

function makeIterator(array) {
    var nextIndex = 0;

    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
}
Run Code Online (Sandbox Code Playgroud)

这是不言自明的。我可以为数组创建一个迭代器:

var iteratorForMyArray = makeIterator([1,2,3,4,5,6,7,8,9, etc])
Run Code Online (Sandbox Code Playgroud)

然后我可以使用我闪亮的新迭代器“迭代地”提取数组的值:

var val0 = iteratorForMyArray.next().value
var val1 = iteratorForMyArray.next().value
etc
Run Code Online (Sandbox Code Playgroud)

我可以理解为什么这在解析 CSV 文件时很有用。我想知道为简单数组创建这样的迭代器是否有任何意义?

我经常发现,虽然简化的示例对理解很有用,但有时很难看出示例何时仅作为示例有用,而实际上在编程中有用。

因为 JavaScript 已经提供了 2 种机制来在数组结构上创建迭代器:

1:基本for循环

for (let i = 0, i < [1,2,3,4,etc]; i++) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

2:Array.prototype.forEach

[1,2,3,4,etc].forEach(function(val, i, arr) {
  ...
})
Run Code Online (Sandbox Code Playgroud)

(我刚刚在这个网站上看到的速度很慢)

问题:

  1. 我的自定义迭代器是否提供这些迭代器不提供的任何东西?
  2. 这两个“内部”迭代器是否都创建了“迭代器”(即我理解的数据结构中值的顺序指针)?还是我离得很远……

Rob*_*obG 1

迭代器的一个很好的特性是每次调用都会获取下一个元素,而forEach则要么全有要么全无(不能提前退出),并且for循环和forEach的所有逻辑都必须位于循环内部。

考虑一个数组迭代器,例如:

function arrayIterator(array) {
  
  // Get array indexes as an array
  var indexes = Object.keys(array)
    .filter(
      // Test for valid Array index property
      key => key == +key && key >= 0 && key.length == String(+key).length)
    // Sort as numbers
    .sort(function(a, b){return a-b});

  // Parameters held in closure
  var current = 0;
  var count = 0;
  var maxCount = indexes.length;

  // Return iterator function
  return function() {
    return ++count > maxCount? 'done' : array[indexes[current++]];
  };
}

var arr = [0,1,,,4,5,6];

// Add non-index numeric property
arr['01'] = '01';
// Add indexable numeric property
arr['10'] = '10';
// Add some other property
arr.foo = 'foo';

var x = arrayIterator(arr);
console.log(x()); // 0
console.log(x()); // 1
console.log(x()); // 4
console.log(x()); // 5
console.log(x()); // 6
console.log(x()); // 10
console.log(x()); // 'done'
console.log(x()); // 'done'
Run Code Online (Sandbox Code Playgroud)

我确信在检查有效索引以及测试调用迭代器时索引是否仍然存在方面还有更多工作要做,但它显示了这个概念。

还需要一些有关在调用之间修改数组时会发生什么情况的文档。