Converter string [] em int [] em uma linha de código usando LINQ


273

Eu tenho uma matriz de números inteiros em forma de seqüência de caracteres:

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

Eu preciso de uma matriz de números inteiros 'reais' para empurrar ainda mais:

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

Eu tentei lançar int e, é claro, falhou:

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

Eu posso fazer a seguir:

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

ou

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

mas ambos parecem feios.

Existem outras maneiras de concluir a tarefa?


3
O que há de errado em simplesmente percorrer uma coleção, converter o valor e adicioná-lo à segunda? Parece bem claro na intenção para mim.
Ed S.


1
Apenas FYI, eu estou usando esta pergunta aqui: stackoverflow.com/questions/1297325/...
Allen Rice


O TryParse não é mais rápido (exceto se suas seqüências de caracteres são inválidas, mas nesse caso você deseja que a exceção o alerte).
usr

Respostas:


609

Dada uma matriz, você pode usar o Array.ConvertAllmétodo :

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

Agradecemos a Marc Gravell por apontar que o lambda pode ser omitido, produzindo uma versão mais curta mostrada abaixo:

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

Uma solução LINQ é semelhante, exceto que você precisaria de uma ToArraychamada extra para obter uma matriz:

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

4
Agradável. Não sabia disso. +1
gastador

O código IL isso gera é realmente menos do que a resposta de Simon Fox, FWIW
Allen Rice

80
Na verdade, você não precisa do lambda; ConvertAll(arr, int.Parse)é suficiente
Marc Gravell

1
O Lambda é necessário no VB.Net 2010: uArray = Array.ConvertAll (sNums.Split (",")), Função (i) UInteger.Parse (i))
BSalita

1
@BSalita Não, no VB.Net éArray.ConvertAll(arr, AddressOf Integer.Parse)
Slai

31

EDIT: para converter em array

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

Isso deve fazer o truque:

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

1
.ToArray () necessária para satisfazer de OP questão
gastador

2
mudança var para int [] e acrescentar .ToArray () se você precisar dele como uma matriz int
Simon Fox

19

Para evitar exceções .Parse, aqui estão algumas .TryParsealternativas.

Para usar apenas os elementos que podem ser analisados:

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 }

ou

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

Alternativas usadas 0para os elementos que não podem ser analisados:

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

ou

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

A segunda solução: var a = Enumerable.Range(0, arr.Length).Where(i => int.TryParse(arr[i], out i)).ToArray();apenas retorna os indeces 0,1,2, ... em vez dos valores reais. Qual é a solução certa aqui?
Beetee

Obrigado @Beetee. Não tenho certeza do que estava pensando com isso. Substituí-o por outra alternativa.
Slai

@ Slai: Obrigado. Mas o que faz new int[0]? Quando tenho de texto, eu não obter um 0em minha matriz ...
Beetee

@Beetee new int[0]é uma matriz int vazia. Os dois primeiros exemplos ignoram valores que não podem ser analisados ​​e os dois últimos exemplos usam 0para valores que não podem ser analisados.
Slai 11/07

@ Slai: Ah, agora entendi. Eu misturei isso new int[] {0}. THX.
Beetee

12

você pode simplesmente converter uma matriz de strings em int array por:

var converted = arr.Select(int.Parse)

5
legais! obrigado. E no VB.netDim converted = arr.Select(addressof Integer.Parse)
Mafu Josh 15/03

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

Você precisa ter certeza de que não está recebendo IEnumerable<int>um retorno


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.