【问题标题】:How do you reset an iterator?如何重置迭代器?
【发布时间】:2018-12-23 14:26:05
【问题描述】:

我正在学习迭代器/生成器,想知道是否有办法让迭代器自行重置?就像你打电话给最后一个.next() 之后有没有办法让它重新启动?

function nextName() {
   const current = names.next().value
  const output = document.querySelector("output")
  if (current) { 
      output.innerText = current.name
    } 
    else { 
     // code to reset it! currently I'm just displaying text
     output.innerText = 'Nothing left'
     }
}

function nameIterator(names) {
  let nextIndex = 0;
  return {
    next: function() {
      return nextIndex < names.length ? 
        { value: names[nextIndex++], done: false } :
        { done: true }
     }
  }
}

这里有一个更清楚的代码笔:https://codepen.io/sammiepls/pen/romyKL?editors=1010

因此,当您单击按钮时,它会调用我的迭代器,每次单击时,它将在 my names 数组中一一显示名称。如何在最后一次点击时将其重置,使其恢复为名字?

所以显示会是这样的:

鲍勃

彼得

莎莉

Bob // 再次获取 Bob

在 codepen 中,我还使用生成器编写了迭代器,无论如何,它是否也能够在通过数组产生后重置回第一个?

【问题讨论】:

  • 你想骑车吗?
  • 我人生中第一次看到“function*”...但是如果你想循环,这应该可以codepen.io/anon/pen/QzvpRw?editors=1010。刚刚修改了 var 的 const 和一些手动代码来重置 UI。

标签: javascript iterator


【解决方案1】:

一般的答案是您不能在 JS 中重置可迭代对象。据我所知,这是设计使然,尽管我不了解决策过程这是用来得出这个结论的。

但是,在您的特定情况下,您不一定要重置迭代器,而是要循环遍历数组。在这种情况下,您可以使用模运算符,如下所示:

function nameIterator(names) {
  let nextIndex = 0;
  return {
    next: function() {
      nextIndex = (nextIndex + 1) % names.length;
      return { value: names[nextIndex], done: false };
    }
  }
}

【讨论】:

  • 啊,我明白了。所以在这种情况下,这是唯一可能的,因为我们正在调整迭代器函数,但我们无法更改 nameGenerator 的工作方式,因为它们不可重置?
【解决方案2】:

为了解决这个问题,当迭代器完成时,像这样重置它:

// code to reset it!
output.innerText = 'Nothing left'
names = nameGenerator(arr);

除非有人证明我错了,否则目前没有方法可以重置我知道的迭代器。

工作 sn-p 示例:

const arr = [ {name: "Bob"}, {name: "Peter"}, {name: "Sally"} ];

let names = nameGenerator(arr);


function nextName() {
   const current = names.next().value
  const output = document.getElementById("output")
   if (current) { 
      output.innerText = current.name
    } 
    else { 
    // code to reset it!
      output.innerText = 'Nothing left'
      names = nameGenerator(arr);
    }
}
  
function nameIterator(names) {
  let nextIndex = 0;
  return {
    next: function() {
      return nextIndex < names.length ? 
        { value: names[nextIndex++], done: false } :
        { done: true }
    }
  }
}

function* nameGenerator() {
  let index = 0;
  while(index < arr.length) {
    yield(arr[index++])
  }
}

 document.querySelector("button").addEventListener("click", nextName)
<button id="button">click me</button>
<p id="output"></p>

【讨论】:

  • 哦,是的,这正是我想要的!不知何故,我无法让这个示例在 codepen 中工作:/ 你添加的只是 else 块中的这个 `names = nameGenerator(arr);` 对吗?
  • @sammiepls 您需要更改 const 名称以让名称
【解决方案3】:

如果索引大于数组索引,您可以更改索引并取余数。

function nameIterator(names) {
    let nextIndex = 0;
    return {
        next: function() {
            nextIndex++;
            nextIndex %= name.length;
            return { value: names[nextIndex], done: false };
        }
    }
}

【讨论】:

    猜你喜欢
    • 2015-01-01
    • 2016-08-17
    • 1970-01-01
    • 2013-07-21
    • 2018-10-29
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多