LINQ: take a sequence of elements from a collection

I have a set of objects and you need to take lots of 100 objects and do some work with them until there are no objects left to be processed.

Instead of iterating over each element and capturing 100 elements, then the next hundred, etc. is there a better way to do this with linq?

Many thanks

+3
source share
5 answers
static void test(IEnumerable<object> objects)
{
    while (objects.Any())
    {
        foreach (object o in objects.Take(100))
        {
        }
        objects = objects.Skip(100); 
    }
}

:)

+10
source
int batchSize = 100;
var batched = yourCollection.Select((x, i) => new { Val = x, Idx = i })
                            .GroupBy(x => x.Idx / batchSize,
                                     (k, g) => g.Select(x => x.Val));

// and then to demonstrate...
foreach (var batch in batched)
{
    Console.WriteLine("Processing batch...");

    foreach (var item in batch)
    {
        Console.WriteLine("Processing item: " + item);
    }
}
+11
source

.

public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> source, int size)
{
    int i = 0;
    List<T> list = new List<T>(size);
    foreach (T item in source)
    {
        list.Add(item);
        if (++i == size)
        {
            yield return list;
            list = new List<T>(size);
            i = 0;
        }
    }
    if (list.Count > 0)
        yield return list;
}
+3

, linq - , . , IEnumerator<T>, Take Skip .

public static void Batch<T>(this IEnumerable<T> items, int batchSize, Action<IEnumerable<T>> batchAction)
{
    if (batchSize < 1) throw new ArgumentException();

    List<T> buffer = new List<T>();
    using (var enumerator = (items ?? Enumerable.Empty<T>()).GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            buffer.Add(enumerator.Current);
            if (buffer.Count == batchSize)
            {
                batchAction(buffer);
                buffer.Clear();
            }
        }

        //execute for remaining items
        if (buffer.Count > 0)
        {
            batchAction(buffer);
        }
    }
}
+2
var batchSize = 100;
for (var i = 0; i < Math.Ceiling(yourCollection.Count() / (decimal)batchSize); i++)
{
    var batch = yourCollection
        .Skip(i*batchSize)
        .Take(batchSize);

    // Do something with batch
}
0

Source: https://habr.com/ru/post/1768206/


All Articles