65 votes

Comment vérifier si une entité est le premier élément d'une boucle foreach ?

Disons que j'ai un foreach boucle.

Je dois faire quelque chose avec le premier objet de la boucle que je ne dois faire avec aucun des autres objets.

Comment puis-je vérifier si l'objet qui est actuellement dans la boucle est le premier objet.

116voto

Filip Cornelissen Points 917

J'aime la méthode Linq, mais sans le Skip(1), de cette façon vous pouvez également l'utiliser pour le dernier élément d'une liste et votre code reste propre imho :)

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

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

    item.otherStuff();
}

15 votes

Je n'aime pas cette approche car elle n'est pas strictement exacte. Si un élément est présent plus d'une fois, par exemple, et qu'il est également le premier ou le dernier élément, alors vous déclenchez la première ou la dernière condition plus d'une fois. Ou si certains éléments sont égaux, ils peuvent également déclencher la condition plus d'une fois.

3 votes

@Sahuagin La question porte sur le test de l'élément pour savoir s'il est premier ou non. Si vous effacez la partie else if, ce qui signifie que vous testez l'élément pour savoir s'il est seulement premier ou non, vos préoccupations légitimes seront apaisées.

63voto

Jerod Houghtelling Points 2426

Vous pouvez le faire de plusieurs façons.

  1. Utilisez un for boucle à la place
  2. Définir un indicateur booléen
  3. Utilisez Linq pour obtenir le list.First() y luego foreach en list.Skip(1)

41voto

geofftnz Points 5844

Quelque chose comme ça :

bool first = true;

foreach(var item in items)
{
    if (first)
    {
        item.firstStuff();
        first = false;
    }
    item.otherStuff();
}

20voto

Ani Points 59747

Voici une solution performante :

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

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

EDIT : Et en voici un en LINQ :

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

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

EDIT : Si les actions sur les éléments ont des signatures assignables à Func<TItem, TResult> que vous pouvez faire :

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

6 votes

Bien que cette méthode satisfasse techniquement aux exigences, elle est nettement moins lisible que l'utilisation d'un drapeau "premier" pour indiquer que d'autres ont posté.

4 votes

Paul : C'est plus efficace, et je ne vois pas pourquoi c'est nettement moins lisible.

0 votes

Je ne vois pas en quoi cela est plus efficace que l'utilisation d'un drapeau "premier".

2voto

Corey Ogburn Points 5146

Il s'agit plutôt d'une solution générale pour obtenir l'index avec chaque objet dans un tableau. Elle devrait fonctionner en testant si c'est la première.

        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);
        }

Dans cette configuration, la clé de la paire clé-valeur est l'index et la valeur est l'objet à cet index, dans mon exemple une chaîne de caractères, mais n'importe quel objet pourrait être placé là. Cela ajoute un peu de surcharge, mais peut être utilisé pour déterminer n'importe quel objet dans l'index de la liste si nécessaire.

0 votes

Ça sent comme le dict de Python. J'aime ça !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X