Vous ne voulez pas utiliser LINQ ici. Vous ne serez pas en mesure d'ordonner et de grouper de la bonne manière sans faire quelque chose de bizarre.
La chose la plus simple à faire est de prendre votre code et de lui faire différer l'exécution en utilisant la fonction yield
déclaration . Une façon simple de procéder est la suivante :
IEnumerable<IEnumerable<T>> SplitIntoSections<T>(this IEnumerable<T> source,
Func<T, bool> sectionDivider)
{
// The items in the current group.
IList<T> currentGroup = new List<T>();
// Cycle through the items.
foreach (T item in source)
{
// Check to see if it is a section divider, if
// it is, then return the previous section.
// Also, only return if there are items.
if (sectionDivider(item) && currentGroup.Count > 0)
{
// Return the list.
yield return currentGroup;
// Reset the list.
currentGroup = new List<T>();
}
// Add the item to the list.
currentGroup.Add(item);
}
// If there are items in the list, yield it.
if (currentGroup.Count > 0) yield return currentGroup;
}
Il y a un problème ici ; pour les très grands groupes, il est inefficace de stocker les sous-groupes dans une liste, ils devraient être diffusés également. Le problème avec votre approche est que vous avez une fonction qui doit être appelée sur chaque élément ; cela interfère avec l'opération de flux puisqu'on ne peut pas réinitialiser le flux en arrière une fois que le groupement est trouvé (comme vous avez effectivement besoin de deux méthodes qui donnent des résultats).