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?

abatishchev
quelle
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.
1
Nur zu Ihrer Information
Allen Rice
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();
Ahmad Mageed
quelle
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));
Simon Fox
quelle
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);
Slai
quelle
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)
A.Dara
quelle
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

rauben
quelle
2
var list = arr.Select(i => Int32.Parse(i));
sepp2k
quelle