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.