web-dev-qa-db-fra.com

Traiter une liste avec une boucle, en prenant 100 éléments à chaque fois et automatiquement moins de 100 à la fin de la liste

Existe-t-il un moyen d’utiliser une boucle qui prend les 100 premiers éléments d’une grande liste, fait quelque chose avec eux, puis les 100 suivants etc.

Actuellement, je dois utiliser deux boucles if: 

for (int i = 0; i < listLength; i = i + 100)
{
    if (i + 100 < listLength)
    {
        //Does its thing with a bigList.GetRange(i, 100)
    }
    else
    {
        //Does the same thing with bigList.GetRange(i, listLength - i)
    }
}

Existe-t-il une meilleure façon de le faire? Sinon, je ferai au moins que la "chose" devienne une fonction afin que le code ne doive pas être copié deux fois.

15
SecondLemon

Vous pouvez utiliser LINQ Skip et Take et votre code sera plus propre.

for (int i = 0; i < listLength; i=i+100)
{
    var items = bigList.Skip(i).Take(100); 
    // Do something with 100 or remaining items
}

Remarque: Si les éléments sont inférieurs à 100, Take vous donnerait les éléments restants.

33
adricadar

Vous pouvez conserver une variable explicite pour le point final:

for (int i = 0, j; i < listLength; i = j)
{
    j = Math.min(listLength, i + 100);
    // do your thing with bigList.GetRange(i, j)
}
4
Ted Hopp
List<int> list = null;
int amount_of_hundreds = Math.Floor(list.Count/100);
int remaining_number = list.Count - (amount_of_hundreds * 100);

for(int i = 0; i < amount_of_hundreds; ++i)
    {
    for(int j = 0; j < 100; ++j)
        {
        int item = list[(i * 100) + j];
        // do what you want with item
        }
    }

 for(int i = 0; i < remaining_number; ++i)
    {
    int item = list[(amount_of_hundreds * 100) + i];
    // do what you want with item
    }
1
user3476093

Je n’aimais aucune des réponses énumérées, alors j’ai créé ma propre extension:

public static class IEnumerableExtensions
{
    public static IEnumerable<IEnumerable<T>> MakeGroupsOf<T>(this IEnumerable<T> source, int count)
    {
        var grouping = new List<T>();
        foreach (var item in source)
        {
            grouping.Add(item);
            if(grouping.Count == count)
            {
                yield return grouping;
                grouping = new List<T>();
            }
        }

        if (grouping.Count != 0)
        {
            yield return grouping;
        }
    }
}

Ensuite, vous pouvez l'utiliser:

foreach(var group in allItems.MakeGroupsOf(100))
{
    // Do something
}
0
Kyle W