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 }
};
si può scrivere:
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();
Funziona se i tuoi elementi sono ordinati d dall'attributo Id. Se non lo fanno, dovrai iniettare una sequenza sull'array originale, che dovrebbe essere facile da fare anche con linq, così otterrai una sequenza.
Inoltre, una migliore alternativa dovrebbe essere:
// 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();
Si noti che queste risposte siano utilizzando LINQ puro.
fonte
2010-04-08 21:23:37
Perché è la condizione nella funzione lambda ' item.Flagged! = prevItem.Flagged '? Dovresti creare un nuovo segmento se il flag cambia da falso a vero. Penso che la condizione dovrebbe essere solo 'item.Flagged', e non dipende affatto dall'elemento precedente. –
@phild: sei corretto, 'item.Flagged' è sufficiente. Avevo fretta e ho interpretato male le aspettative dell'OP. Ho aggiornato la mia risposta. – LBushkin
+1, metodo di estensione molto utile :) –