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.