2013-04-10 11 views

risposta

16

Si potrebbe fare questo attraverso Enumerable.Zip:

bool sequential = values.Zip(values.Skip(1), (a,b) => (a+1) == b).All(x => x); 

Questo funziona prendendo ogni coppia di valori, e controllare per vedere se il secondo è 1 più del primo, e il ritorno booleani. Se tutte le coppie soddisfano i criteri, i valori sono sequenziali.


Dato che questa è una lista di interi, si può fare questo un po 'più efficiente utilizzando:

bool sequential = values.Skip(1).Select((v,i) => v == (values[i]+1)).All(v => v); 

questo funziona solo su sequenze a cui si accede tramite un indice. Si noti che utilizziamo values[i], non values[i-1], poiché la chiamata Skip sposta effettivamente gli indici.

+0

@dtb Grazie per averlo risolto ... –

+0

+1. Penso che si possa fare anche con Aggregate (mantieni la differenza) per evitare di ripetere la sequenza più volte ... Proverò a scriverlo più tardi come risposta ... –

+0

@AlexeiLevenkov La mia seconda opzione esegue solo una volta una iterazione, ma dipende sequenza è una lista. Posso vedere come farlo con 'Aggregate', ma solo se fai il tuo lambda avere effetti collaterali sgradevoli ... :( –

10
bool isSequential = Enumerable.Range(values.Min(), values.Count()) 
           .SequenceEqual(values); 
+0

Non so perché questa non è stata selezionata come risposta: è straordinariamente semplice – user1830285

2

Un'altra opzione è quella di utilizzare Aggregate per iterare la sequenza una sola volta.

Si noti che diversamente All suggerito da Reed Copsey Aggregate non si può fermare a metà quando la condizione non riesce ...

var s = new int[] {3,4,5,6}.ToList(); 

var isSequential = s.Aggregate 
    (
     new {PrevValue = 0, isFirst = true, Success = true} , 
     (acc, current) => 
      new { 
        PrevValue = current, 
        isFirst = false, 
        Success = acc.Success && (acc.isFirst || (acc.PrevValue == current - 1)) 
       } 
) 
    .Success; 

Fancier versione sarebbe quella di avere iteratore che porta valore precedente lungo o un codice speciale che avrebbe split iterator su "First and the rest" che consente di implementare la soluzione di Reed con un'unica iterazione per ogni enumerabile.

+0

Aggiunto 'ToList()' dato che la domanda riguardava una lista. versioni più fantasiose! –

+1

+1 Funziona - ma sforna molta memoria per le liste di grandi dimensioni e non può causare un cortocircuito sul successo ... Preferisco comunque entrambe le mie opzioni (il mio secondo, in particolare, è più efficiente se sapere che è una lista ). –

-1

Se sai già che i numeri che avete nella vostra lista è unico, e anche risolto, quindi il controllo più semplice per sequenziale è solo

lst[lst.Count - 1] - lst[0] == lst.Count - 1 

Si supponga atleast 1 elemento della lista.

Problemi correlati