2010-06-29 9 views
6

Wenn ich zum Beispiel die folgende Zeichenfolge:eine getrennte Zeichenfolge in eine Liste Shove <int>

„123; 3344; 4334; 12“

und ich möchte diese Zahlen in einem allgemeinen List<int>, ich denke, ich Ich kenne keinen guten Weg hier, außer in eine Schleife zu teilen und eine Umwandlung durchzuführen, dann zu einer List<int> durch jede Iteration hinzuzufügen. Hat jemand andere Möglichkeiten, dies zu tun?

Aktualisiert. Folgendes habe ich mir ausgedacht. Ich möchte dies auf alte Weise machen, nicht mit LINQ, weil ich versuche, mit Strings, Arrays, Listen und Manipulationen und Konvertierungen im Allgemeinen besser zu werden.

public List<int> StringToList(string stringToSplit, char splitDelimiter) 
{ 
    List<int> list = new List<int>(); 

    if (string.IsNullOrEmpty(stringToSplit)) 
     return list; 

    string[] values = stringToSplit.Split(splitDelimiter); 

    if (values.Length <= 1) 
     return list; 

    foreach (string s in values) 
    { 
     int i; 
     if (Int32.TryParse(s, out i)) 
      list.Add(i); 
    } 

    return list; 
} 

Dies ist ein neues String Utility Methode, die ich über die Verwendung planen, wann immer ich eine getrennte Zeichenfolge Liste konvertieren müssen zur Liste

Also zurück an den Aufrufer ich eine leere Liste zurückkehrt, wenn etwas schiefgeht. Gut schlecht? ist es ziemlich üblich, dies zu tun?

Ja, es gibt mehr "elegante" Möglichkeiten, dies mit LINQ zu tun, aber ich möchte es manuell tun .. die alte Weise für jetzt nur für mein eigenes Verständnis.

Auch, was stört mich dazu:

list.AddRange(str.Split(';').Select(Int32.Parse)); 

ist, dass ich keine Ahnung habe:

  1. Wie es stattdessen in einer TryParse zu schieben.
  2. Was passiert, wenn die str.Split(';').Select(Int32.Parse) nur aus irgendeinem Grund fehlschlägt ... dann wird die Methode, in der diese AddRange residiert, explodieren, und wenn ich nicht einen Versuch/Fang um die ganze Sache hinzufügen, bin ich geschraubt, wenn ich es nicht tue handle es richtig.
+0

Mit TryParse ist hier ist ein schwerwiegender Fehler: http://en.wikipedia.org/wiki/GIGO –

Antwort

5
string str = "123;3344;4334;12"; 
List<int> list = new List<int>(); 

foreach (string s in str.Split(';')) 
{ 
    list.Add(Int32.Parse(s)); 
} 
+1

+1, lesen Sie den Titel! Ich würde vorschlagen, TryParse anstelle von Parse zu verwenden. –

+0

Ich wuunder, wenn Sie nur tun können Liste list = "123; 3344; 4334; 12" .Split (";"); Ich weiß, dass Sie mit einem Array können: string [] list = "123; 3344; 4334; 12" .Split (";"); – PositiveGuy

+1

@kaffee, nein. Sie können nicht implizit von einem String-Array in eine 'List ' konvertieren. Außerdem sollte es "Split (';')" sein. Beachten Sie das einfache Anführungszeichen, da es sich um ein Zeichenliteral handelt. –

3
List<int> list = (from numString in "123;3344;4334;12".Split(';') 
        select int.Parse(numString)).ToList(); 
6
static int? ToInt32OrNull(string s) 
{ 
    int value; 
    return (Int32.TryParse(s, out value)) ? value : default(int?);  
} 
// ... 
var str = "123;3344;4334;12"; 
var list = new List<int>(); 
list.AddRange(str.Split(';') 
       .Select(ToInt32OrNull) 
       .Where(i => i != null) 
       .Cast<int>()); 

Frager Hinweise:

Ich weiß nicht, von einer guten Art und Weise hier anders als in einer Schleife zu spalten und eine Umwandlung dann zu einer Liste hinzufügen tun

In der Regel ist dies ein Hauptgrund, warum LINQ in C# gebracht wurde - zu re Verschieben Sie die Notwendigkeit, mit einer Reihe von Werten zu arbeiten, indem Sie Schleifen implementieren, und erklären Sie stattdessen einfach Ihre Absicht, die Sequenz zu transformieren. Wenn Sie sich jemals denken "Ich weiß nicht, wie ich das machen soll, außer mit einer Schleife" - ist es an der Zeit, in ein LINQ-Konstrukt zu schauen, das die Arbeit für Sie erledigen wird.

Performance Update:

Leistung von LINQ wurde unter quesioned. Während in den Kommentaren die Idee, dass LINQ langsamer ist, verteidigt wird, da wir die Vorteile der Lesbarkeit, Wartbarkeit und Zusammensetzbarkeit erhalten, gibt es einen anderen Aspekt, der LINQ einen leichten Leistungsvorteil gibt: Parallelität. Hier ist ein Beispiel, bei dem das Hinzufügen von nur einem Erweiterungs-Methodenaufruf AsParallel() die Leistung verdoppelt. Dies ist ein großartiges Beispiel dafür, wo Scale-Out die Mikrooptimierung übertrifft, ohne dass man sehr sorgfältig messen muss.Hinweis: Ich behaupte nicht, dass Mikrooptimierungen nicht immer benötigt werden, aber mit den Werkzeugen, die wir auf dieser Ebene der Abstraktion zur Verfügung haben, wird das Bedürfnis verschwindend klein.

class Program 
{ 
    private const int ElementCount = 10000000; 

    static void Main(string[] args) 
    { 
     var str = generateString(); 
     var stopwatch = new Stopwatch(); 

     var list1 = new List<int>(ElementCount); 
     var list2 = new List<int>(ElementCount); 

     var split = str.Split(';'); 

     stopwatch.Start(); 
     list1.AddRange(split 
          .Select(ToInt32OrNull) 
          .Where(i => i != null) 
          .Cast<int>()); 
     stopwatch.Stop(); 

     TimeSpan nonParallel = stopwatch.Elapsed; 

     stopwatch.Restart(); 

     list2.AddRange(split 
          .AsParallel() 
          .Select(ToInt32OrNull) 
          .Where(i => i != null) 
          .Cast<int>()); 

     stopwatch.Stop(); 

     TimeSpan parallel = stopwatch.Elapsed; 

     Debug.WriteLine("Non-parallel: {0}", nonParallel); 
     Debug.WriteLine("Parallel: {0}", parallel); 
    } 

    private static String generateString() 
    { 
     var builder = new StringBuilder(1048576); 
     var rnd = new Random(); 

     for (int i = 0; i < ElementCount; i++) 
     { 
      builder.Append(rnd.Next(99999)); 
      builder.Append(';'); 
     } 

     builder.Length--; 

     return builder.ToString(); 
    } 

    static int? ToInt32OrNull(string s) 
    { 
     int value; 
     return (Int32.TryParse(s, out value)) ? value : default(int?); 
    } 
} 

Nicht parallel: 00: 00: 07,0719911

Parallel: 00: 00: 04,5933906

+0

ja ich frage mich, ob die Leistung im Vergleich zur Standardaufteilung in einer Schleife – PositiveGuy

+0

@coffeeaddict: Es ist fast immer vernachlässigbar, und es sollte nur für eine Änderung berücksichtigt werden, wenn es gemessen und gefunden wird ein Problem sein, hier ist ein guter, neuer Vergleich: http://jerrytech.blogspot.com/2010/02/revisiting-c-loop-performance.html – codekaizen

+0

Ich weiß nicht, dass ich immer hier LINQ auch in diesem verwenden kann es kann beginnen, ein peformance Schwein zu sein. Nicht sagend, dass du falsch liegst ... ja – PositiveGuy

1
string myString = "123;3344;4334;12"; 
var ints = new List<int>(); 
(from s in myString.Split(';') 
select int.Parse()).ToList().ForEach(i=>ints.Add(i)); 

Ich habe gehört, 4.0 .NET hinzugefügt haben ForEach zu Enumerable<T>, so dass die ToList dort möglicherweise nicht notwendig ist (kann nicht testen).

+0

Nach der 'ToList' hast du * eine Liste von Ints. Das 'ForEach' ist nicht erforderlich. –

+0

@Matthew Flaschen, einverstanden. Mein ursprünglicher (und zugegebenermaßen hastiger) erster Gedanke war, dass die Liste möglicherweise nicht originell ist und der Inhalt möglicherweise erhalten werden muss. d. h. Anhängen der Ergebnisse an eine bestehende Liste ohne Ersatz. –

-1

Ich denke, das einfachste

var str = "123;3344;4334;12"; 
    var list = str.Split(';').ToList().Cast<int>(); 
+0

-1: Dies funktioniert nie, weil Sie keine Zeichenfolge an eine Ganzzahl übergeben können. Sie können es nur analysieren (mit 'int.Parse()' oder 'int.TryParse()'). – Oliver

Verwandte Themen