Saltar al contenido

Cómo recorrer IEnumerable en lotes

este problema se puede solucionar de diferentes formas, pero te damos la solución más completa para nosotros.

Solución:

Puede usar el operador por lotes de MoreLINQ (disponible en NuGet):

foreach(IEnumerable batch in users.Batch(1000))
   // use batch

Si el uso simple de la biblioteca no es una opción, puede reutilizar la implementación:

public static IEnumerable> Batch(
        this IEnumerable source, int size)

    T[] bucket = null;
    var count = 0;

    foreach (var item in source)
    
       if (bucket == null)
           bucket = new T[size];

       bucket[count++] = item;

       if (count != size)                
          continue;

       yield return bucket.Select(x => x);

       bucket = null;
       count = 0;
    

    // Return the last bucket with all remaining elements
    if (bucket != null && count > 0)
    
        Array.Resize(ref bucket, count);
        yield return bucket.Select(x => x);
    

Por cierto, para el rendimiento, simplemente puede devolver el cubo sin llamar Select(x => x). Select está optimizado para matrices, pero el delegado del selector aún se invocaría en cada elemento. Entonces, en tu caso es mejor usar

yield return bucket;

Parece que necesita usar los métodos Saltar y Tomar de su objeto. Ejemplo:

users.Skip(1000).Take(1000)

esto omitiría los primeros 1000 y tomaría los siguientes 1000. Solo necesitaría aumentar la cantidad omitida con cada llamada

Puede usar una variable entera con el parámetro para Omitir y puede ajustar cuánto se omite. A continuación, puede llamarlo en un método.

public IEnumerable GetBatch(int pageNumber)

    return users.Skip(pageNumber * 1000).Take(1000);

La forma más fácil de hacer esto es probablemente simplemente usar el GroupBy método en LINQ:

var batches = myEnumerable
    .Select((x, i) => new  x, i )
    .GroupBy(p => (p.i / 1000), (p, i) => p.x);

Pero para una solución más sofisticada, vea esta publicación de blog sobre cómo crear su propio método de extensión para hacer esto. Reproducido aquí para la posteridad:

public static IEnumerable> Batch(this IEnumerable collection, int batchSize)

    List nextbatch = new List(batchSize);
    foreach (T item in collection)
    
        nextbatch.Add(item);
        if (nextbatch.Count == batchSize)
        
            yield return nextbatch;
            nextbatch = new List(); 
            // or nextbatch.Clear(); but see Servy's comment below
        
    

    if (nextbatch.Count > 0)
        yield return nextbatch;

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *