Converti la stringa [] in int [] in una riga di codice usando LINQ


273

Ho una matrice di numeri interi in forma di stringa:

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

Ho bisogno di un array di numeri interi "reali" per spingerlo ulteriormente:

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

Ho provato a lanciare int e ovviamente non è riuscito:

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

Posso fare il prossimo:

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

o

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

ma entrambi sembrano brutti.

Esistono altri modi per completare l'attività?


3
Cosa c'è di sbagliato nel semplice iterare attraverso una raccolta, convertire il valore e aggiungerlo al secondo? Mi sembra abbastanza chiaro nelle intenzioni.
Ed S.


1
Cordiali saluti, sto usando questa domanda qui: stackoverflow.com/questions/1297325/…
Allen Rice


TryParse non è più veloce (tranne se le stringhe non sono valide, ma in tal caso si desidera che l'eccezione ti avvisi).
usr

Risposte:


609

Dato un array puoi usare il Array.ConvertAllmetodo :

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

Grazie a Marc Gravell per aver sottolineato che la lambda può essere omessa, producendo una versione più breve mostrata di seguito:

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

Una soluzione LINQ è simile, ad eccezione del fatto che ToArrayper ottenere un array è necessaria la chiamata aggiuntiva :

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

4
Bello. Non lo sapevo. +1
spender

Il codice IL che genera è in realtà inferiore alla risposta di Simon Fox, FWIW
Allen Rice,

80
In realtà, non hai bisogno della lambda; ConvertAll(arr, int.Parse)è sufficiente
Marc Gravell

1
Lambda è necessario in VB.Net 2010: uArray = Array.ConvertAll (sNums.Split (","), Function (i) UInteger.Parse (i))
BSalita,

1
@BSalita No, in VB.Net èArray.ConvertAll(arr, AddressOf Integer.Parse)
Slai,

31

EDIT: per convertire in array

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

Questo dovrebbe fare il trucco:

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

1
.ToArray () richiesto per soddisfare la domanda di OP
spender

2
cambia var in int [] e aggiungi .ToArray () se ne hai bisogno come array int
Simon Fox,

19

Per evitare eccezioni .Parse, ecco alcune .TryParsealternative.

Per utilizzare solo gli elementi che possono essere analizzati:

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 }

o

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

Alternative che usano 0per gli elementi che non possono essere analizzati:

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

o

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

La seconda soluzione: var a = Enumerable.Range(0, arr.Length).Where(i => int.TryParse(arr[i], out i)).ToArray();restituisce solo gli indici 0,1,2, ... invece dei valori reali. Qual è la soluzione giusta qui?
Beetee,

Grazie @Beetee. Non sono sicuro di cosa stavo pensando. L'ho sostituito con un'altra alternativa.
Slai,

@Slai: grazie. Ma che cosa fa new int[0]? Quando ho un messaggio, non ne trovo uno 0nel mio array ...
Beetee,

@Beetee new int[0]è un array int vuoto. I primi due esempi saltano i valori che non possono essere analizzati e gli ultimi due esempi usano 0valori che non possono essere analizzati.
Slai,

@Slai: Ah ora capisco. L'ho confuso con new int[] {0}. Grazie.
Beetee,

12

puoi semplicemente trasmettere un array di stringhe all'array int:

var converted = arr.Select(int.Parse)

5
simpatico! grazie. E in VB.NetDim converted = arr.Select(addressof Integer.Parse)
Mafu Josh,

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

Fare in modo che non si ottiene un IEnumerable<int>come un ritorno


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.