编写循环的简洁方法,该循环具有集合中第一个项目的特殊逻辑

Ian*_*ose 12 c# collections

通常我必须编写一个循环,它必须特殊情况下集合中的第一个项目,代码似乎永远不应该是清晰的.

如果没有重新设计C#语言,那么编写这些循环的最佳方法是什么?

// this is more code to read then I would like for such a common concept
// and it is to easy to forget to update "firstItem"
foreach (x in yyy)
{
  if (firstItem)
  {
     firstItem = false;
     // other code when first item
  }
  // normal processing code
}

// this code is even harder to understand
if (yyy.Length > 0)
{
   //Process first item;
   for (int i = 1; i < yyy.Length; i++)
   {  
      // process the other items.
   }
}
Run Code Online (Sandbox Code Playgroud)

Ani*_*Ani 13

怎么样:

using (var erator = enumerable.GetEnumerator())
{
    if (erator.MoveNext())
    {
        ProcessFirst(erator.Current);
        //ProcessOther(erator.Current); // Include if appropriate.

        while (erator.MoveNext())
            ProcessOther(erator.Current);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以将其转换为扩展名:

public static void Do<T>(this IEnumerable<T> source, 
                         Action<T> firstItemAction,
                         Action<T> otherItemAction)
{
   // null-checks omitted

    using (var erator = source.GetEnumerator())
    {
        if (!erator.MoveNext())
            return;

        firstItemAction(erator.Current);

        while (erator.MoveNext())
           otherItemAction(erator.Current);            
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果只有某人可以为此扩展方法提供**明确的**名称. (3认同)

ili*_*ian 5

我很想使用一点linq

using System.Linq;

var theCollectionImWorkingOn = ...

var firstItem = theCollectionImWorkingOn.First();
firstItem.DoSomeWork();

foreach(var item in theCollectionImWorkingOn.Skip(1))
{
    item.DoSomeOtherWork();
}
Run Code Online (Sandbox Code Playgroud)

  • `firstItem`逻辑应该包含在一个检查中,以确保集合中有任何元素...... (3认同)

Sco*_*ski 5

你可以尝试:

collection.first(x=>
{
    //...
}).rest(x=>
{
    //...
}).run();
Run Code Online (Sandbox Code Playgroud)

第一个/休息看起来像:

FirstPart<T> first<T>(this IEnumerable<T> c, Action<T> a)
{
    return new FirstPart<T>(c, a);
}

FirstRest rest<T>(this FirstPart<T> fp, Action<T> a)
{
    return new FirstRest(fp.Collection, fp.Action, a);
}
Run Code Online (Sandbox Code Playgroud)

您需要定义分类的FirstPart和FirstRest.FirstRest需要像这样的run方法(Collection,FirstAction和RestAction属性):

void run()
{
    bool first = true;
    foreach (var x in Collection)
    {
        if (first) {
            FirstAction(x);
            first = false;
        }
        else {
             RestAction(x);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 而不是第一次和休息,你可以使用头部和尾部.更实用:) (2认同)