2012-11-23 8 views
6

Spero di trovare un modo migliore (magari con una bella espressione di linq) per convertire una lista di stringhe come "41,42x, 43" a una lista di lunghi validi. Il codice seguente funziona, ma sembra solo brutto.Alla ricerca di un modo pulito per convertire una lista di stringhe in Elenco valido <long> in C#

string addressBookEntryIds = "41,42x,43"; 
var ids = addressBookEntryIds.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries); 
var addressBookEntryIdList =new List<long>(); 
foreach (var rec in ids) 
{ 
    long val; 
    if (Int64.TryParse(rec, out val)) 
    { 
     addressBookEntryIdList.Add(val); 
    } 
} 

risposta

4
string addressBookEntryIds = "41,42x,43"; 

Func<string, long?> safeParse = (s) => { 
      long val; 
      if (Int64.TryParse(s, out val)) 
      { 
       return val; 
      } 
      return null;  
}; 


var longs = (from s in addressBookEntryIds.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries) 
      let cand = safeParse(s) 
      where cand.HasValue 
      select cand.Value).ToList(); 
+0

Ho provato questo in Linqpad; Faccio qualcosa di simile con input non sicuri nel mio codice, ma i miei dati sorgente provengono effettivamente da SQL. Non dirò che questo è più carino in alcun modo - penso che il tuo codice originale sia perfetto. È conciso, chiaro e al punto. – SAJ14SAJ

3

uso regex

var list = Regex.Matches(@"41,42x,43", @"\d+").Cast<Match>().Select(x => Convert.ToInt64(x.Value)).ToList(); 
+0

che possono o non possono funzionare a seconda del modulo di voci. 42x43 creerebbe due voci, non zero come dovrebbe basarsi sull'implementazione di riferimento. – SAJ14SAJ

0

Solo una derivazione del codice, del tutto ridondante (usa TryParse e quindi analizzare di nuovo), ma penso che funziona:

addressBookEntryIds.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries) 
        .Where(id => 
        { 
         long val; 
         return Int64.TryParse(id, out val); 
        }) 
        .Select(id => Int64.Parse(id)); 
+0

ringrazia tutti per il loro contributo. Tutto aiuta. –

1

Beh, ecco una versione LINQ, ma non è poi così brutta!

string addressBookEntryIds = "41,42x,43"; 
var ids = addressBookEntryIds.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); 

Int64 converted; // Working value used within the select 
IEnumerable<Int64> values = ids.Select(x => new 
{ 
    Success = Int64.TryParse(x, out converted), 
    Value = converted 
}).Where(x => x.Success) 
    .Select(x => x.Value); 

La differenza tra questa soluzione e Anderson è che TryParse è chiamato solo una volta per l'ingresso.

1

Ecco un'altra versione LINQ:

String addressBookEntryIds = "41,42x,43"; 
Int64 val = 0; 

addressBookEntryIds 
    .Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries) 
    .Where(id => Int64.TryParse(id, out val)) 
    .Select(id => val) 
    .ToList() 

Se si preferisce un'espressione di query, è possibile utilizzare:

from id in addressBookEntryIds.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries) 
where Int64.TryParse(id, out val) 
select val 
Problemi correlati