Considérant:
var arrayOfElements = new[] {
new { Id = 1, Flagged = true },
new { Id = 2, Flagged = false },
new { Id = 3, Flagged = false },
new { Id = 4, Flagged = true },
new { Id = 5, Flagged = false },
new { Id = 6, Flagged = false },
new { Id = 7, Flagged = false },
new { Id = 8, Flagged = true },
new { Id = 9, Flagged = false }
};
Vous pouvez écrire:
var grouped =
from i in arrayOfElements
where i.Flagged
select
(new[] { i.Id })
.Union(arrayOfElements.Where(i2 => i2.Id > i.Id).TakeWhile(i2 => !i2.Flagged).Select(i2 => i2.Id))
.ToArray();
Cela fonctionne si vos éléments sont ordere d par l'attribut Id. Si ce n'est pas le cas, vous devrez injecter une séquence sur votre tableau d'origine, ce qui devrait aussi être facile avec linq, donc vous obtiendrez une séquence.
En outre, une meilleure alternative devrait être:
// for each flagged element, slice the array,
// starting on the flagged element until the next flagged element
var grouped =
from i in arrayOfElements
where i.Flagged
select
arrayOfElements
.SkipWhile(i2 => i2 != i)
.TakeWhile(i2 => i2 == i || !i2.Flagged)
.Select(i2 => i2.Id)
.ToArray();
Notez que ces réponses utilisent LINQ pure.
Pourquoi la condition dans la fonction lambda ' item.Flagged! = prevItem.Flagged '? Vous créez un nouveau segment si l'indicateur passe de false à true. Je pense que la condition devrait être juste "item.Flagged", et pas dépendant de l'élément précédent du tout. –
@phild: Vous avez raison, 'item.Flagged' est suffisant. J'étais pressé plus tôt et j'ai mal interprété les attentes du PO. J'ai mis à jour ma réponse. – LBushkin
+1, méthode d'extension très utile :) –