2010-08-24 15 views

Respuesta

32

Hay varias maneras que usted podría hacer eso.

  1. utilizar un bucle en lugar
  2. Establecer una bandera booleana
  3. utilizar LINQ para obtener el list.First() y luego foreach sobre list.Skip (1)
18

Algo como esto:

bool first = true; 

foreach(var item in items) 
{ 
    if (first) 
    { 
     item.firstStuff(); 
     first = false; 
    } 
    item.otherStuff(); 
} 
2
bool first = true; 
foreach(var foo in bar) 
{ 
    if (first) 
    { 
    // do something to your first item 
    first = false; 
    } 
    // do something else to the rest 
} 
+0

GRR, no es rápido ¡suficiente! no vi la publicación de geofftnz. – Hamza

+2

es la raza de pregunta fácil patentada StackOverflow :) – geofftnz

+1

bien jugado señor, felicidades :) – Hamza

2

No se puede pensar en otra cosa que

var processedFirst = false; 
foreach(var x in items) { 
    if(!processedFirst) { 
     ProcessFirst(x); 
     processedFirst = true; 
    } 
11

Aquí hay una solución performant:

using (var erator = enumerable.GetEnumerator()) 
{ 
    if (erator.MoveNext()) 
    { 
     DoActionOnFirst(erator.Current); 

     while (erator.MoveNext()) 
      DoActionOnOther(erator.Current); 
    } 
} 

EDIT: Y aquí hay una LINQ uno:

if (enumerable.Any()) 
    { 
     DoActionOnFirst(enumerable.First()); 

     foreach (var item in enumerable.Skip(1)) 
      DoActionOnOther(item); 
    } 

EDIT: Si las acciones en los artículos tienen firmas asignables a Func<TItem, TResult>, que puede hacer:

enumerable.Select((item, index) => index == 0 ? GetResultFromFirstItem(item) : GetResultFromOtherItem(item)); 
+3

Si bien esto cumple técnicamente con los requisitos, es significativamente menos legible que el uso de una "primera" bandera para indicar que otros han publicado. –

+2

@ Paul: Es más eficiente, y no veo por qué es significativamente menos legible. – Ani

+0

No estoy seguro de cómo esto es más eficiente si se compara con el uso de una bandera 'primera'. – Babar

2

prueba este

bool IsFirst = true; 

foreach(DataRow dr in dt.Rows) 
{ 
    if (IsFirst) 
    { 
     // do some thing 
     IsFirst = false; 
    }  
} 
4

Esto es más que una solución general para obtener el índice junto con cada objeto en una matriz. Debería probar las pruebas si es la primera.

 List<String> entries = new List<string>(); 
     entries.Add("zero"); 
     entries.Add("one"); 
     entries.Add("two"); 

     Dictionary<int, String> numberedEntries = new Dictionary<int, string>(); 
     int i = 0; 
     entries.ForEach(x => numberedEntries.Add(i++, x)); 
     foreach (KeyValuePair<int, String> pair in numberedEntries) { 
      Console.WriteLine(pair.Key + ": " + pair.Value); 
     } 

En esta configuración, la clave de la KeyValuePair es el índice y el valor es el objeto en ese índice, en mi ejemplo una cadena, pero cualquier objeto fuera colocado allí. Agrega un poco de sobrecarga, pero puede usarse para determinar cualquier objeto en el índice de la lista cuando sea necesario.

+0

Huele como el dict de Python.__items__ ¡Me gusta! – Hovis

61

me gusta la forma en LINQ, pero sin el salto (1), de esta manera también se puede utilizar para el último elemento de la lista y su código permanece en mi humilde opinión limpia :)

foreach(var item in items) 
{ 
    if (items.First()==item) 
     item.firstStuff(); 

    else if (items.Last() == item) 
     item.lastStuff(); 

    item.otherStuff(); 
} 
+5

No me gusta este enfoque porque no es estrictamente preciso. Si un artículo está presente más de una vez, por ejemplo, y también es el primero o el último elemento, disparará la primera o la última condición más de una vez. o si algunos artículos tienen igualdad, también pueden dispararlo más de una vez. –

+0

@Sahuagin La pregunta se trata de probar el artículo en primer lugar o no. Si borra la parte else si, lo que significa que está probando el artículo por ser el primero o no, sus preocupaciones correctas serán suavizadas. – ErTR

Cuestiones relacionadas