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

时间:2017-07-10 03:40:30

标签: 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};
       }
    };
}

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

var iteratorForMyArray = makeIterator([1,2,3,4,5,6,7,8,9, etc])

然后我可以使用我的闪亮的新迭代器来反复地&#39;拉出我的数组的值:

var val0 = iteratorForMyArray.next().value
var val1 = iteratorForMyArray.next().value
etc

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

我经常发现虽然简化的例子对于理解很有用,但有时很难看出这个例子只是作为一个例子而有用,而且在编程中实际上很有用。

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

1:基本for循环

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

2:Array.prototype.forEach

[1,2,3,4,etc].forEach(function(val, i, arr) {
  ...
})

(我刚看到this网站上的速度很慢)

问题:

  1. 我的自定义迭代器是否提供了这些迭代器不会做的任何事情?
  2. 在内部做这些事情&#39;迭代器创建&#39;迭代器&#39; (即我理解为数据结构中值的顺序指针)?或者我离开了几英里......

2 个答案:

答案 0 :(得分:2)

ForEach保证顺序,以及它会跳过无效索引等。与循环标准相比,你的迭代器不提供任何额外的东西,它只会变慢,因为你&# 39;重新调用一个函数来获取下一个项目,其中一个基本的for循环没有这个开销。使用for循环并缓存长度以启动以获得更好的性能。

答案 1 :(得分:1)

迭代器的一个很好的特性是每个调用都获得下一个元素,而 forEach 它是全部或全部(你不能提前退出),并且同时使用 for loop和 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'

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

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