是否有更短/更简单的for循环版本到x次?

mbx*_*mbx 51 .net c#

通常我们使用计数器执行类似for或while循环的操作:

for (int i = 0; i < 10; i++)
{
    list.Add(GetRandomItem());
}
Run Code Online (Sandbox Code Playgroud)

但有时你会混淆边界.你可以使用while循环,但如果你犯了一个错误,这个循环是无限的......

以Perl为例,我会使用更明显的

for(1..10){
    list->add(getRandomItem());
}
Run Code Online (Sandbox Code Playgroud)

有没有像"doitXtimes(10){...}"这样的东西?

Jon*_*eet 62

那么你可以轻松编写自己的扩展方法:

public static void Times(this int count, Action action)
{
    for (int i = 0; i < count; i++)
    {
        action();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以写:

10.Times(() => list.Add(GetRandomItem()));
Run Code Online (Sandbox Code Playgroud)

我不确定我是否真的建议你这样做,但这是一个选择.我不相信框架中有类似的东西,尽管你可以使用Enumerable.RangeEnumerable.Repeat创建一个适当长度的懒惰序列,这在某些情况下很有用.


从C#6开始,您仍然可以方便地访问静态方法而无需创建扩展方法,使用using static指令导入它.例如:

// Normally in a namespace, of course.
public class LoopUtilities
{
    public static void Repeat(int count, Action action)
    {
        for (int i = 0; i < count; i++)
        {
            action();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后当你想要使用它时:

using static LoopUtilities;

// Class declaration etc, then:
Repeat(5, () => Console.WriteLine("Hello."));
Run Code Online (Sandbox Code Playgroud)

  • 如果没有额外的"()=>"=)有一些语法会很好 (4认同)
  • 我建议在中间会见以下妥协:+ i +.操作将增加操作前的一半值和操作后的一半.这样,双方都可以满意. (4认同)
  • @Yacoder:不,它不会,因为那时代码的含义是模棱两可的. (3认同)

Gro*_*ozz 41

foreach (var i in Enumerable.Range(0, N))
{
    // do something
}
Run Code Online (Sandbox Code Playgroud)

  • 当您需要索引时,这个版本很好。 (2认同)
  • 这是我要去的那个,因为它提供了一种简洁但清晰的迭代方式.我觉得它比Paul的答案更紧凑,尽管它们确实是同一个解决方案. (2认同)

Pau*_*ane 34

可以创建一个IEnumerableInt32:

Enumerable.Range(0, 10);
Run Code Online (Sandbox Code Playgroud)

的ForEach扩展方法也是众所周知的(虽然不能与.NET发货).你可以将两者结合起来:

Enumerable.Range(0, 10).ForEach(index => ...);
Run Code Online (Sandbox Code Playgroud)

所以你的例子将成为:

Enumerable.Range(0, 10).ForEach(_ => list.Add(GetRandomItem()));
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一句,我没有 ForEach 没有 ToList 函数 Enumerable.Range(0, 10).ToList().ForEach(i =&gt; sb.AppendLine($"{i}")); 他们应该为此做一些专门的 lambda。 (3认同)

Ale*_*sky 12

我看到Jon Skeet 打败了我,但是这个变化将允许你在每次运行时将索引传递给Action:

public static class IntegerExtensions
{
  public static void TimesWithIndex(this int count, Action<int> action)
  {
     for (int i = 0; i < count; i++)
        action(i);
  }
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

10.TimesWithIndex((i) =>
            obj[i].DoSomething());
Run Code Online (Sandbox Code Playgroud)


aai*_*mnr 6

while (i-- > 0) {

}
Run Code Online (Sandbox Code Playgroud)

你提到 while 循环很危险,因为它可能是无限的——上面的形式非常简单,永远不会是无限的。至少完全无限:)

它既方便又简短(比任何其他答案都短)并且将精确运行i次(因为后缀递减在递减之前返回值)。

  • 您错过了变量声明和初始化,这将使您的版本低于请求的“for(1..10)”和通过扩展方法选择的“int.Times”答案。 (4认同)

A. *_*rel 5

还缺少一种方法:

List<T> list = System.Linq.Enumerable.Range(0, 10).Select(_ => GetRandomItem()).ToList();
Run Code Online (Sandbox Code Playgroud)

其中 T 是 GetRandomItem() 返回的类型

  • 对,我刚刚编辑了帖子以纠正我的错误。谢谢 (2认同)