2014-04-17 13 views
6

Korzystam z następującego kodu, aby podzielić ciąg na listę < int>, jednak czasami ciąg zawiera wartości nie całkowite, które są obsługiwane w inny sposób.Podziel ciąg na listę <int> ignoruj ​​brak wartości int

Przykładem ciąg może być tak: 1,2,3,4, x

kod

wygląda następująco:

List<int> arrCMs = new List<int>(strMyList.Split(',').Select(x => int.Parse(x))); 

Problemem jest to tak szybko, jak to uderza w „x” to Zgłasza błąd, ponieważ "x" nie może być analizowany jako liczba całkowita.

Jak mogę go zignorować wartości nie całkowite? Jestem pewien, że powinienem móc coś zrobić z int.TryParse, ale nie mogę tego rozgryźć.

Dzięki

Odpowiedz

11
List<int> arrCMs = strMyList.Split(',') 
    .Select(possibleIntegerAsString => { 
     int parsedInteger = 0; 
     bool isInteger = int.TryParse(possibleIntegerAsString , out parsedInteger); 
     return new {isInteger, parsedInteger}; 
    }) 
    .Where(tryParseResult => tryParseResult.isInteger) 
    .Select(tryParseResult => tryParseResult.parsedInteger) 
    .ToList(); 

Pierwszy Select w powyższym przykładzie zwraca anonymous type opisujący wynik int.TryParse - to znaczy, czy był to ważny całkowitą, a jeżeli więc jaka była wartość.

Klauzula Where odfiltrowuje te, które nie były prawidłowe.

Drugi Select następnie pobiera przeanalizowane wartości z ciągów, które mogły zostać przeanalizowane.

+1

+1, aby uzyskać najbardziej wydajną odpowiedź. –

+2

Fajnie, choć myślę, że odpowiedź Andrzeja jest odrobinę przyjemniejsza. –

0

Zmiana ta

int result; 
List<int> arrCMs = 
      new List<int>(strMyList.Split(',') 
            .Where(x => int.TryParse(x, out result)) 
            .Select(int.Parse)); 
+0

Zapomniałeś słowa kluczowego "out". – dcastro

+0

@dcastro Dziękuję. Robiłem to na miejscu. lol –

+0

Również rzucanie łańcucha na int nie powiedzie się. – dcastro

0

kolejny, używając Array.ForEach

List<int> ints = new List<int>(); 
Array.ForEach(strMyList.Split(','), s => 
    { 
     int i; 
     if (int.TryParse(s, out i)){ ints.Add(i);} 
    }); 
6

Krótkie i słodkie, używając int.TryParse:

List<int> nums = list 
    .Split(',') 
    .Select(i => 
    { 
     int val; 
     return int.TryParse(i, out val) ? (int?)val : null; 
    }) 
    .Where(i => i.HasValue) 
    .Cast<int>() 
    .ToList() 

przykład roboczych:http://dotnetfiddle.net/4wyoAM

+1

+1 za niestosowanie typów anonimowych, gdy nie musisz. –

-1

Parse tylko raz dla każdej wartości, ale nieco zdradliwy.

int result = 0; 
List<int> arrCMs = strMyList.Split(',') 
          .Where(x => int.TryParse(x, out result)) 
          .Select(x => result) 
          .ToList(); 
0

Działka Twist: użyć starej szkoły foreach pętlę.

List<int> arrCMs = new List<int>(); 
foreach (string str in strMyList.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries)) 
{ 
    int res; 
    if (int.TryParse(str, out res)) 
    { 
     arrCMs.Add(res); 
    } 
}  

Można również utworzyć metodę dla niego i skorzystać z bloku iteratora za pomocą yield return:

public static IEnumerable<int> ParseIntegers(string val, char seperator = ',') 
{ 
    foreach (string str in val.Split(new [] { seperator }, StringSplitOptions.RemoveEmptyEntries)) 
    { 
     int res; 
     if (int.TryParse(str, out res)) 
     { 
      yield return res; 
     } 
    } 
} 

ta jest prawdopodobnie zbyt inżynierii jeśli to tylko do jednorazowego użytku.