2012-11-23 16 views
6

Mam nadzieję znaleźć lepszy sposób (może z ładnym wyrażeniem linq), aby przekonwertować listę ciągów, np. "41,42x, 43" na lista ważnych longów. Poniższy kod działa, ale po prostu jest brzydki.Szukasz prostego sposobu na przekonwertowanie listy ciągów do prawidłowej listy <long> w 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); 
    } 
} 

Odpowiedz

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

Testowałem to w Linqpad; Robię coś podobnego z niebezpiecznymi danymi wejściowymi w moim kodzie, ale moje dane źródłowe faktycznie pochodzą z SQL. Nie powiem, że to jest w jakikolwiek sposób ładniejsze - myślę, że twój oryginalny kod jest w porządku. Jest zwięzły, jasny i na temat. – SAJ14SAJ

3

wykorzystanie regex

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

, które mogą lub nie mogą pracować w zależności od formy wpisy. 42x43 tworzyłoby dwa wpisy, a nie zero, jak powinno na podstawie implementacji referencyjnej. – SAJ14SAJ

0

Tylko wyprowadzenie kodu, całkiem zbędna (używa TryParse a następnie zanalizować ponownie), ale myślę, że to działa:

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

dziękuję wszystkim za ich wkład. To wszystko pomaga. –

1

Cóż, tutaj wersja LINQ, ale tak naprawdę nie jest wcale brzydsza!

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); 

Różnica między tym roztworze i Andersona jest to, że TryParse jest wywoływana tylko raz na wejściu.

1

Oto kolejna wersja 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() 

Jeśli wolisz wyrażenie kwerendy, można użyć:

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