Considerando:
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 }
};
puede escribir:
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();
Esto funciona si tus elementos son ordere d por el atributo Id. Si no lo hacen, tendrás que inyectar una secuencia en tu matriz original, que también debería ser fácil de hacer con linq, por lo que obtendrás una secuencia.
Además, una mejor alternativa debe ser:
// 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();
Tenga en cuenta que esas respuestas están utilizando LINQ puro.
¿Por qué es la condición en la función lambda ' item.Flagged! = prevItem.Flagged '? Debería crear un nuevo segmento si la bandera cambia de falso a verdadero. Creo que la condición debería ser solo 'item.Flagged', y no dependiente del ítem anterior en absoluto. –
@phild: tiene razón, 'item.Flagged' es suficiente. Tenía prisa antes y malinterpreté las expectativas del OP. He actualizado mi respuesta. – LBushkin
+1, método de extensión muy útil :) –