有多种方法可以找出
for
和 for...in
循环的最后一次迭代。但是如何找到 for...of
循环中的最后一次迭代。我在文档中找不到。
for (item of array) {
if (detect_last_iteration_here) {
do_not_do_something
}
}
一种方法是使用 Array.prototype.entries():
for (const [i, value] of arr.entries()) {
if (i === arr.length - 1) {
// do your thing
}
}
另一种方法是像 Shidersz 所建议的那样在循环之外进行计数。我认为您不想检查
indexOf(item)
,因为如果最后一个项目在数组中的其他位置重复,就会出现问题...
一种可能的方法是在循环外初始化一个计数器,并在每次迭代时递减它:
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;}
请注意,
!--iterations
计算为 !(--iterations)
,当 true
时,表达式将为 iterations=1
。
您可以对数组进行切片并省略最后一个元素。
var array = [1, 2, 3],
item;
for (item of array.slice(0, -1)) {
console.log(item)
}
使用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
}
一个更通用的替代方案,牢固地基于组合原则,是使用生成器函数实现另一个迭代器。事实上,这将组成这两个迭代器。
新迭代器基本上会将值的实际生成委托给原始迭代器。不同之处在于,前者总是比后者“领先一步”。通过这样做,新的迭代器将能够验证每个元素的迭代是否已停止到下一个元素。
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()];
}
}
请注意,在第一次迭代中,
next
被调用两次。对于以下每次迭代,next
始终被调用一次,仅针对与当前迭代提前一步相对应的元素。
详细了解 JavaScript 迭代协议,了解有关该实现的更多信息。
更具体的例子:
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.`);
}
由于此解决方案中没有使用索引或迭代器的实际长度等概念(后者在某些极端情况下甚至不是无限迭代器),因此这种方法非常适合任何类型的迭代器。
另一个例子:
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.`);
}
如果您想根据特定索引更改循环行为,那么在 for 循环中使用显式索引可能是个好主意。
如果您只是想跳过最后一个元素,您可以执行类似的操作
for (item of array.slice(0, -1)) {
//do something for every element except last
}
似乎没有任何关于此的规范。 似乎有两种解决方法:
如果可以的话,只需将一个标记推到数组的末尾并对该标记进行操作,如下所示:
myArray.push('FIN')
for (el of myArray){
if (el === 'FIN')
//ending code
}
或者,您可以使用下面的方法来获取可与 Array.length 一起使用的索引
找到最后一个循环并在迭代过程中删除最后一个逗号插入的最简单方法是将数组的长度与其最后一项的索引进行比较。
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');
}
}
const chain = ['ABC', 'BCA', 'CBA'];
let findOut;
for (const lastIter of chain) {
findOut = lastIter; //Last iteration value stored in each iteration.
}
console.log(findOut);
使用以下方法,您可以找到
for...of
循环中的最后一次迭代:
let iCount = 0;
for( const obj of arrObjects) {
iCount = iCount + 1;
if (iCount < arrObjects.length) {
// Some code to execute on first to (last - 1) elements
}
else {
// Some code only for the last element
}
}
您还可以将
Array.prototype.at()
与 -1
Array.prototype.at()
上的MDN 以供参考。
您的示例将如下所示:
for (item of array) {
if (item === array.at(-1)) {
// do_not_do_something
}
}