Convierta la cadena [] a int [] en una línea de código usando LINQ


273

Tengo una serie de enteros en forma de cadena:

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

Necesito una variedad de enteros 'reales' para impulsarlo aún más:

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

Traté de lanzar int y, por supuesto, falló:

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

Puedo hacer lo siguiente:

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

pero ambos se ven feos.

¿Hay alguna otra forma de completar la tarea?


3
¿Qué tiene de malo simplemente iterar a través de una colección, convertir el valor y agregarlo a la segunda? Parece bastante claro en intención para mí.
Ed S.


1
Solo para su información, estoy usando esta pregunta aquí: stackoverflow.com/questions/1297325/…
Allen Rice


TryParse no es más rápido (excepto si sus cadenas no son válidas, pero en ese caso desea que la excepción le avise).
usr

Respuestas:


609

Dada una matriz, puede usar el Array.ConvertAllmétodo :

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

Gracias a Marc Gravell por señalar que la lambda se puede omitir, produciendo una versión más corta que se muestra a continuación:

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

Una solución LINQ es similar, excepto que necesitaría una ToArrayllamada adicional para obtener una matriz:

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

44
Agradable. No lo sabía. +1
gastador

El código IL que esto genera es en realidad menor que la respuesta de Simon Fox, FWIW
Allen Rice

80
En realidad, no necesitas la lambda; ConvertAll(arr, int.Parse)es suficiente
Marc Gravell

1
Se necesita Lambda en VB.Net 2010: uArray = Array.ConvertAll (sNums.Split (","), Function (i) UInteger.Parse (i))
BSalita

1
@BSalita No, en VB.Net esArray.ConvertAll(arr, AddressOf Integer.Parse)
Slai

31

EDITAR: para convertir a matriz

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

Esto debería funcionar:

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

1
.ToArray () requerido para satisfacer la pregunta de OP
gastador

2
var a cambio int [] y añadir .ToArray () si la necesita como una matriz int
Simon Fox

19

Para evitar excepciones con .Parse, aquí hay algunas .TryParsealternativas.

Para usar solo los elementos que se pueden analizar:

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

Alternativas que utilizan 0para los elementos que no se pueden analizar:

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 segunda solución: var a = Enumerable.Range(0, arr.Length).Where(i => int.TryParse(arr[i], out i)).ToArray();solo devuelve las indeces 0,1,2, ... en lugar de los valores reales. ¿Cuál es la solución correcta aquí?
Beetee

Gracias @Beetee. No estoy seguro de lo que estaba pensando con eso. Lo reemplacé con otra alternativa.
Slai

@Slai: Gracias. Pero que hace new int[0]? Cuando tengo el texto, no obtener una 0en mi serie ...
Beetee

@Beetee new int[0]es una matriz int vacía. Los primeros dos ejemplos omiten valores que no se pueden analizar, y los dos últimos ejemplos se usan 0para valores que no se pueden analizar.
Slai

@Slai: Ah, ahora lo entiendo. Lo mezclé con new int[] {0}. Gracias.
Beetee

12

simplemente puede emitir una matriz de cadenas a la matriz int mediante:

var converted = arr.Select(int.Parse)

55
¡bonito! gracias. Y en VB.NetDim converted = arr.Select(addressof Integer.Parse)
Mafu Josh

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

Debes asegurarte de que no recibes IEnumerable<int>una devolución


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.