2015-10-21 85 views
6

ho il seguente scenario quando si raggruppa una collezione:C# IEnumerable.Count() genera IndexOutOfRangeException

var result = data.GroupBy(x => x.Name.Split(new char[] { '-' })[1].Trim()); 

dove variabile di dati è di tipo ObservableCollection<Data>

Quando controllo per

if(result.Count()>0) 

getta un IndexOutOfRangeException

ovviamente ciò accade perché l'operazione di divisione delle stringhe genera un'eccezione.

La domanda è: c'è un modo per verificare se il risultato del raggruppamento non è nullo ed evitare l'eccezione?

+3

Si sta dividendo per '-' e si accede a questo array all'indice 1 che è il secondo elemento. Ovviamente non c'è un secondo elemento perché non c'era '-'. Quindi non ha nulla a che fare con 'null'. –

+0

Sì, lo so, c'è un modo per verificare la lunghezza della matrice all'interno del gruppo per istruzione? –

+0

resut.Any() potrebbe fare il trucco? –

risposta

10

Prima di tutto, Enumerable.Count solo esegue la query LINQ eseguito differita (GroupBy usa esecuzione differita, guardare il sezione osservazioni). Quindi non è la colpa di Count.

Si sta dividendo per - e si accede a questo array all'indice 1 che è il secondo elemento. Ovviamente non esiste un secondo elemento perché non c'era lo -. Quindi non ha nulla a che fare con null.

Forse è sufficiente prendere solo quelle in cui v'è un secondo token:

var result = data 
.Select(x => new{ Data = x, Split = x.Name.Split(new char[] { '-' }) }) 
.Where(x => x.Split.Length >= 2) 
.GroupBy(x => x.Split[1].Trim()); 

oppure la seconda se v'è un secondo, altrimenti la prima:

var result = data 
.Select(x => new{ Data = x, Split = x.Name.Split(new char[] { '-' }) }) 
.GroupBy(x => x.Split.Length >= 2 ? x.Split[1].Trim() : x.Split[0].Trim()); 
+0

... o anche un gruppo con un nome di gruppo vuoto (qualcosa di simile) var result = data.GroupBy (x => (x.Name! = null && x.Name.Contains ('-'))? x.Name.Split (new char [] {'-'}) [1] .Trim(): ""); –

+0

Ottima risposta Tim, grazie mille –

2

Si può fare lo seguente:

var result = data.GroupBy(x => x.Name.Contains('-') ? x.Name.Split('-')[1].Trim() : ""); 

Se non ti piace il :? operatore o lo vogliono meno compatto, uso:

var result = data.GroupBy(x => 
{ 
    string name = x.Name; 
    if (name.Contains('-')) return name.Split('-')[1].Trim(); 
    return ""; 
}); 

Nota: ho usato Split('-') invece di Split(new char[] { '-' })

Questo è probabilmente più intuitivo rispetto alla soluzione di Tim Schmelter, ma utilizzare ciò che si desidera.