使用for each循环时如何确定最后一次循环?

50

当在对象上执行'foreach'循环时,我希望对最后一次循环迭代进行不同的操作。我正在使用Ruby,但对于C#、Java等也是如此。

  list = ['A','B','C']
  list.each{|i|
    puts "Looping: "+i # if not last loop iteration
    puts "Last one: "+i # if last loop iteration
  }

期望的输出结果等同于:

  Looping: 'A'
  Looping: 'B'
  Last one: 'C'

显而易见的解决方法是使用 'for i in 1..list.length' 将代码迁移到 for 循环中,但 for each 的解决方案更为优美。在循环期间编写特殊情况的最优雅的方式是什么?是否可以使用 foreach 完成?


感谢所有出色而且多样化的回答。我当然能理解人们所说的关于集合不一定有顺序的观点。但是有时候,集合确实具有顺序,我不明白为什么 for each 循环不能仍然适用。 - Matt
1
很抱歉我只能选择一个答案,但我确实喜欢它们中的大部分。 - Matt
1
@MattChurchy,很遗憾你没有选择更好的一个。 - KingNestor
25个回答

0
这个怎么样?刚学了一点点Ruby。呵呵呵
list.collect {|x|(x!=list.last ? "Looping:"+x:"Lastone:"+x) }.each{|i|puts i}      

好主意,但是你是按值比较的,所以像 ['A', 'B', 'C', 'D', 'C'] 这样的列表会得到最后两个元素。也许如果你使用 !x.equal?(list.last) 更好。 - Firas Assaad
我知道我需要比较引用而不是值,但我还不知道如何在Ruby中实现。所以equal?用于比较引用? - anonymous
我喜欢简洁明了,我确实有一个现实世界的用例,在这个用例中,我知道数组值是唯一的。(这实际上是为测试代码而不是生产使用。)所以对我来说,这很好。虽然它不严格需要分别收集和打印。 - Matt

0

另一种不必重写foreach循环就能工作的模式:

var delayed = null;
foreach (var X in collection)
{
    if (delayed != null)
    {
        puts("Looping");
        // Use delayed
    }
    delayed = X;
}

puts("Last one");
// Use delayed

这样编译器可以保持循环的规范,迭代器(包括那些没有计数的)按预期工作,并将最后一个与其他变量分离。

当我想要在迭代之间发生某些事情,但是不要在最后一次迭代之后时,我也会使用此模式。在这种情况下,X 通常使用,delayed 指的是其他东西,并且延迟的使用仅在循环开头,无需在循环结束后执行任何操作。


0

从列表中删除最后一个并保留其值。

Spec spec = specs.Find(s=>s.Value == 'C');
  if (spec != null)
  {
    specs.Remove(spec);
  }
foreach(Spec spec in specs)
{

}

-1

尽可能使用join

大多数情况下,所有元素之间的分隔符都相同,只需使用语言中相应的函数将它们连接在一起即可。

Ruby示例:

puts array.join(", ")

这应该涵盖99%的情况,如果不是,将数组分成头和尾。

Ruby示例,

*head, tail = array
head.each { |each| put "looping: " << each }
puts "last element: " << tail 

-5

<hello>我们在这里想些什么?

public static void main(String[] args) {
    // TODO Auto-generated method stub
    String str = readIndex();
    String comp[] = str.split("}");

    StringBuffer sb = new StringBuffer();
    for (String s : comp) {
        sb.append(s);
        sb.append("}\n");
    }
    System.out.println (sb.toString());
}

作为一种建模符号,OMT符号的影响占主导地位(例如,使用矩形表示类和对象)。尽管Booch的“云”符号被取消了,但是Booch指定低级设计细节的能力得到了采纳。来自Objectory的用例符号和Booch的组件符号已与其余符号集成,但在UML 1.1中,语义集成相对较弱,并且直到UML 2.0的重大修订才真正解决。


1
看看Animesh的另一个回答,完全离题了。可能是机器人? - dotjoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接