Konvertieren Sie den String [] mit LINQ in eine Codezeile in int []


273

Ich habe ein Array von Ganzzahlen in Zeichenfolgenform:

var arr = new string[] { "1", "2", "3", "4" };

Ich brauche eine Reihe von 'echten' ganzen Zahlen, um es weiter voranzutreiben:

void Foo(int[] arr) { .. }

Ich habe versucht, int zu besetzen und es ist natürlich gescheitert:

Foo(arr.Cast<int>.ToArray());

Ich kann als nächstes tun:

var list = new List<int>(arr.Length);
arr.ForEach(i => list.Add(Int32.Parse(i))); // maybe Convert.ToInt32() is better?
Foo(list.ToArray());

oder

var list = new List<int>(arr.Length);
arr.ForEach(i =>
{
   int j;
   if (Int32.TryParse(i, out j)) // TryParse is faster, yeah
   {
      list.Add(j);
   }
 }
 Foo(list.ToArray());

aber beide sehen hässlich aus.

Gibt es andere Möglichkeiten, um die Aufgabe abzuschließen?


3
Was ist falsch daran, einfach eine Sammlung zu durchlaufen, den Wert zu konvertieren und zur zweiten hinzuzufügen? Scheint mir in der Absicht ziemlich klar zu sein.
Ed S.




TryParse ist nicht schneller (außer wenn Ihre Zeichenfolgen ungültig sind, aber in diesem Fall möchten Sie, dass die Ausnahme Sie benachrichtigt).
usr

Antworten:


608

Bei einem gegebenen Array können Sie die folgende Array.ConvertAllMethode verwenden :

int[] myInts = Array.ConvertAll(arr, s => int.Parse(s));

Vielen Dank an Marc Gravell für den Hinweis, dass das Lambda weggelassen werden kann, was zu einer kürzeren Version führt:

int[] myInts = Array.ConvertAll(arr, int.Parse);

Eine LINQ-Lösung ist ähnlich, außer dass Sie den zusätzlichen ToArrayAufruf benötigen würden , um ein Array zu erhalten:

int[] myInts = arr.Select(int.Parse).ToArray();

4
Nett. Wusste das nicht. +1
Spender

Der IL-Code, den dies generiert, ist tatsächlich weniger als die Antwort von Simon Fox, FWIW
Allen Rice,

80
Eigentlich brauchst du das Lambda nicht; ConvertAll(arr, int.Parse)ist ausreichend
Marc Gravell

1
Lambda wird in VB.Net 2010 benötigt: uArray = Array.ConvertAll (sNums.Split (","), Funktion (i) UInteger.Parse (i))
BSalita

1
@BSalita Nein, in VB.Net ist esArray.ConvertAll(arr, AddressOf Integer.Parse)
Slai

31

BEARBEITEN: Zum Konvertieren in ein Array

int[] asIntegers = arr.Select(s => int.Parse(s)).ToArray();

Dies sollte den Trick tun:

var asIntegers = arr.Select(s => int.Parse(s));

1
.ToArray () erforderlich, um die Frage von OP zu erfüllen
Spender

2
Ändern Sie var in int [] und fügen Sie .ToArray () hinzu, wenn Sie es als int-Array benötigen
Simon Fox

19

Um Ausnahmen mit zu vermeiden .Parse, finden Sie hier einige .TryParseAlternativen.

So verwenden Sie nur die Elemente, die analysiert werden können:

string[] arr = { null, " ", " 1 ", " 002 ", "3.0" };
int i = 0; 
var a = (from s in arr where int.TryParse(s, out i) select i).ToArray();  // a = { 1, 2 }

oder

var a = arr.SelectMany(s => int.TryParse(s, out i) ? new[] { i } : new int[0]).ToArray();

Alternativen 0für die Elemente, die nicht analysiert werden können:

int i; 
var a = Array.ConvertAll(arr, s => int.TryParse(s, out i) ? i : 0); //a = { 0, 0, 1, 2, 0 }

oder

var a = arr.Select((s, i) => int.TryParse(s, out i) ? i : 0).ToArray();

C # 7.0 :

var a = Array.ConvertAll(arr, s => int.TryParse(s, out var i) ? i : 0);

Die zweite Lösung: var a = Enumerable.Range(0, arr.Length).Where(i => int.TryParse(arr[i], out i)).ToArray();Gibt nur die Indizes 0,1,2, ... anstelle der realen Werte zurück. Was ist hier die richtige Lösung?
Beetee

Danke @Beetee. Ich bin mir nicht sicher, was ich damit gedacht habe. Ich habe es durch eine andere Alternative ersetzt.
Slai

@ Slai: Danke. Aber was macht das new int[0]? Wenn ich Text habe, bekomme ich keinen 0in meinem Array ...
Beetee

@Beetee new int[0]ist ein leeres int-Array. In den ersten beiden Beispielen werden Werte übersprungen, die nicht analysiert werden können, und in den letzten beiden Beispielen werden 0Werte verwendet, die nicht analysiert werden können.
Slai

@ Slai: Ah jetzt verstehe ich es. Ich habe es verwechselt mit new int[] {0}. Vielen Dank.
Beetee

12

Sie können einfach ein String-Array in ein int-Array umwandeln, indem Sie:

var converted = arr.Select(int.Parse)

5
nett! Danke. Und in VB.NetDim converted = arr.Select(addressof Integer.Parse)
Mafu Josh

3
var asIntegers = arr.Select(s => int.Parse(s)).ToArray(); 

Stellen Sie sicher, dass Sie keine IEnumerable<int>Rückgabe erhalten


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.