简体   繁体   English

在 ES6 javascript 中检测 FOR OF 循环中的最后一次迭代

[英]Detect last iteration in FOR OF loop in ES6 javascript

There are multiple ways of finding out the last iteration of a for and for...in loop.有多种方法可以找出forfor...in循环的最后一次迭代。 But how do I find the last iteration in a for...of loop.但是我如何在for...of循环中找到最后一次迭代。 I could not find that in the documentation.我在文档中找不到。

for (item of array) {
    if (detect_last_iteration_here) {
        do_not_do_something
    }
}

One possible way is to initialize a counter outside the loop, and decrement it on every iteration:一种可能的方法是在循环外初始化一个计数器,并在每次迭代时递减它:

 const data = [1, 2, 3]; let iterations = data.length; for (item of data) { if (!--iterations) console.log(item + " => This is the last iteration..."); else console.log(item); }
 .as-console {background-color:black !important; color:lime;} .as-console-wrapper {max-height:100% !important; top:0;}

Note that !--iterations is evaluated as !(--iterations) and the expression will be true when iterations=1 .请注意, !--iterations被评估为!(--iterations)并且当iterations=1时表达式将为true

One approach is using Array.prototype.entries() :一种方法是使用Array.prototype.entries()

for (const [i, value] of arr.entries()) {
    if (i === arr.length - 1) {
        // do your thing
    }
}

Another way is keeping a count outside the loop like Shidersz suggested.另一种方法是像 Shidersz 建议的那样将计数保持在循环之外。 I don't think you want to check indexOf(item) though because that poses a problem if the last item is duplicated somewhere else in the array...我不认为你想检查indexOf(item)因为如果最后一个项目在数组中的其他地方重复,这会带来问题......

You could slice the array and omit the last element.您可以对数组进行切片并省略最后一个元素。

 var array = [1, 2, 3], item; for (item of array.slice(0, -1)) { console.log(item) }

If you want to change your loop behavior based the specific index, then it's probably a good idea to use an explicit index in your for-loop.如果您想根据特定索引更改循环行为,那么在 for 循环中使用显式索引可能是个好主意。

If you simply want to skip out on the last element, you can do something like如果您只是想跳过最后一个元素,您可以执行以下操作

for (item of array.slice(0, -1)) {
    //do something for every element except last
}

The simpliest way to find the last loop and, let's say, get rid of the last comma insert during iterration is to compare the length of array with the index of its last item.找到最后一个循环的最简单方法,比方说,在迭代过程中去掉最后一个逗号插入,是将数组的长度与其最后一项的索引进行比较。

const arr = ["verb", "noun", "pronoun"];

for (let item of arr) {
    if (arr.length -1 !== arr.indexOf(item)) {
        console.log('With Commas');
    } else {
        console.log('No Commars');
    }
}

There doesnt seem to be anything the the spec for for..of for this.似乎没有任何关于 for..of 的规范。 There seems to be two work-arounds:似乎有两种解决方法:

If you can, just push a marker to the end of the array and act on that marker, like so:如果可以,只需将一个标记推到数组的末尾并对该标记进行操作,如下所示:

myArray.push('FIN')
for (el of myArray){
    if (el === 'FIN')
        //ending code
}

Alternatively, you can use the below to get an index you can use in tandem with an Array.length或者,您可以使用以下内容来获取可以与 Array.length 一起使用的索引

enter link description here 在此处输入链接描述

pre> 
const chain = ['ABC', 'BCA', 'CBA'];
let findOut;
for (const lastIter of chain) {
    findOut = lastIter;       //Last iteration value stored in each iteration. 
} 

console.log(findOut);控制台日志(查找);

enter code here
CBA

A more generalized alternative, firmly based in composition principles, is implement another iterator using a generator function.一个更通用的替代方案,牢固地基于组合原则,是使用生成器函数实现另一个迭代器。 This will, in fact, compose these two iterators.事实上,这将组合这两个迭代器。

The new iterator will basically delegate the actual yielding of the values to the original iterator.新的迭代器基本上会将值的实际产生委托给原始迭代器。 The difference is that the former will alyaws be “one step ahead” of the latter.不同的是,前者会比后者“领先一步”。 By doing so, the new iterator will be capable of verify, for each element, if the iteration has stopped with the next one.通过这样做,新的迭代器将能够为每个元素验证迭代是否在下一个元素时停止。

function* withLast(iterable) {
  const iterator = iterable[Symbol.iterator]();
  let curr = iterator.next();
  let next = iterator.next();
  while (!curr.done) {
    yield [next.done, curr.value];
    [curr, next] = [next, iterator.next()];
  }
}

Notice that, in the first iteration, next is called twice.请注意,在第一次迭代中, next被调用了两次。 For each of the following iterations, next is always called once, only for the element that corresponds one step ahead of the current iteration.对于next每次迭代, next总是被调用一次,仅针对当前迭代前一步对应的元素。

Learn more about the JavaScript iteration protocols to learn more about that implementation.了解有关JavaScript 迭代协议的更多信息,以了解有关该实现的更多信息。

A little more concrete example:一个更具体的例子:

 function* withLast(iterable) { const iterator = iterable[Symbol.iterator](); let curr = iterator.next(); let next = iterator.next(); while (!curr.done) { yield [next.done, curr.value]; [curr, next] = [next, iterator.next()]; } } const arr = [1, 2, 3]; for (const [isLast, element] of withLast(arr)) { console.log(`${element} ${isLast ? 'is' : 'is not'} the last.`); }

As concepts like index or the actual length of the iterator – the latter which isn't even a thing in some corner cases as infinite iterators – aren't used in this solution, this approach is well suited for any kind of iterator.由于像索引或迭代器的实际长度这样的概念——后者在某些极端情况下甚至不是无限迭代器——在这个解决方案中没有使用,这种方法非常适合任何类型的迭代器。

Another example:另一个例子:

 function* withLast(iterable) { const iterator = iterable[Symbol.iterator](); let curr = iterator.next(); let next = iterator.next(); while (!curr.done) { yield [next.done, curr.value]; [curr, next] = [next, iterator.next()]; } } // Generator function that creates a "generic" iterator: function* gen() { yield 'a'; yield 'b'; yield 'c'; } for (const [isLast, element] of withLast(gen())) { console.log(`${element} ${isLast ? 'is' : 'is not'} the last.`); }

With ES6, by calling the entries() method on the array you can do it =>使用 ES6,通过调用数组上的 entries() 方法,您可以做到 =>

const array = [1, 2, 3];
for (const [i, v] of array.entries()) {
    //Handled last iteration
    if( i === array.length-1) {
        continue;
    }
    console.log(i, v)// it will print index and value
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM