Mat*_*att 48 c# ruby java foreach loops
我想在对象上执行'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
}
Run Code Online (Sandbox Code Playgroud)
所需的输出相当于:
Looping: 'A'
Looping: 'B'
Last one: 'C'
Run Code Online (Sandbox Code Playgroud)
显而易见的解决方法是使用代码将代码迁移到for循环'for i in 1..list.length',但for each解决方案感觉更优雅.在循环期间编写特殊情况的最优雅方法是什么?可以用foreach完成吗?
Big*_*jim 38
我在这里看到很多复杂的,难以理解的代码......为什么不保持简单:
var count = list.Length;
foreach(var item in list)
if (--count > 0)
Console.WriteLine("Looping: " + item);
else
Console.Writeline("Lastone: " + item);
Run Code Online (Sandbox Code Playgroud)
这只是一个额外的声明!
另一种常见情况是,您希望使用最后一项执行额外或更少操作,例如在项目之间放置分隔符:
var count = list.Length;
foreach(var item in list)
{
Console.Write(item);
if (--count > 0)
Console.Write(",");
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*rdt 37
foreach结构(在Java中肯定也可能在其他语言中)用于表示迭代时最常见的类型,其中包括对没有有意义的迭代顺序的集合进行迭代.例如,基于散列的集合没有排序,因此没有 "最后一个元素".每次迭代时,最后一次迭代可能会产生不同的元素.
基本上:不,foreach结构并不意味着以这种方式使用.
ano*_*ous 23
如何先获取对最后一项的引用,然后在foreach循环中使用它进行比较?我并不是说你应该这样做,因为我自己会使用KlauseMeier提到的基于索引的循环.抱歉,我不知道Ruby,所以下面的示例是在C#中!希望你不介意:-)
string lastItem = list[list.Count - 1];
foreach (string item in list) {
if (item != lastItem)
Console.WriteLine("Looping: " + item);
else Console.Writeline("Lastone: " + item);
}
Run Code Online (Sandbox Code Playgroud)
我修改了以下代码,通过引用比较而不是值(只能使用引用类型而不是值类型).以下代码应该支持包含相同字符串(但不是相同的字符串对象)的多个对象,因为MattChurcy的示例没有指定字符串必须是不同的,我使用LINQ Last方法而不是计算索引.
string lastItem = list.Last();
foreach (string item in list) {
if (!object.ReferenceEquals(item, lastItem))
Console.WriteLine("Looping: " + item);
else Console.WriteLine("Lastone: " + item);
}
Run Code Online (Sandbox Code Playgroud)
上述代码的局限性.(1)它只适用于字符串或引用类型而不是值类型.(2)同一对象只能在列表中出现一次.您可以拥有包含相同内容的不同对象.文字字符串不能重复使用,因为C#不会为具有相同内容的字符串创建唯一对象.
我也不傻.我知道基于索引的循环是要使用的循环.当我第一次发布初步答案时,我已经说过了.我在问题的背景下提供了最好的答案.我太累了,不能继续解释这个,所以你们都投票删除我的答案.如果这个消失,我会很高兴的.谢谢
kgi*_*kis 22
这够优雅吗?它假定一个非空列表.
list[0,list.length-1].each{|i|
puts "Looping:"+i # if not last loop iteration
}
puts "Last one:" + list[list.length-1]
Run Code Online (Sandbox Code Playgroud)
Dav*_*ows 13
在Ruby中我会each_with_index在这种情况下使用
list = ['A','B','C']
last = list.length-1
list.each_with_index{|i,index|
if index == last
puts "Last one: "+i
else
puts "Looping: "+i # if not last loop iteration
end
}
Run Code Online (Sandbox Code Playgroud)
您可以eachwithlast在类中定义一个方法,使其与each除最后一个元素之外的所有元素相同,但最后一个方法则为其他元素:
class MyColl
def eachwithlast
for i in 0...(size-1)
yield(self[i], false)
end
yield(self[size-1], true)
end
end
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样调用它(foo作为其实例MyColl或子类):
foo.eachwithlast do |value, last|
if last
puts "Last one: "+value
else
puts "Looping: "+value
end
end
Run Code Online (Sandbox Code Playgroud)
编辑:遵循molf的建议:
class MyColl
def eachwithlast (defaultAction, lastAction)
for i in 0...(size-1)
defaultAction.call(self[i])
end
lastAction.call(self[size-1])
end
end
foo.eachwithlast(
lambda { |x| puts "looping "+x },
lambda { |x| puts "last "+x } )
Run Code Online (Sandbox Code Playgroud)
C#3.0或更新版本
首先,我会写一个扩展方法:
public static void ForEachEx<T>(this IEnumerable<T> s, Action<T, bool> act)
{
IEnumerator<T> curr = s.GetEnumerator();
if (curr.MoveNext())
{
bool last;
while (true)
{
T item = curr.Current;
last = !curr.MoveNext();
act(item, last);
if (last)
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用新foreach的很简单:
int[] lData = new int[] { 1, 2, 3, 5, -1};
void Run()
{
lData.ForEachEx((el, last) =>
{
if (last)
Console.Write("last one: ");
Console.WriteLine(el);
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50157 次 |
| 最近记录: |