Convertir la chaîne [] en int [] en une seule ligne de code à l'aide de LINQ


273

J'ai un tableau d'entiers sous forme de chaîne:

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

J'ai besoin d'un tableau de «vrais» entiers pour aller plus loin:

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

J'ai essayé de lancer int et cela a bien sûr échoué:

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

Je peux faire ensuite:

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

mais les deux ont l'air moche.

Existe-t-il d'autres moyens de terminer la tâche?


3
Qu'y a-t-il de mal à simplement parcourir une collection, à convertir la valeur et à l'ajouter à la seconde? Cela me semble assez clair.
Ed S.


1
Juste pour info, j'utilise cette question ici: stackoverflow.com/questions/1297325/…
Allen Rice


TryParse n'est pas plus rapide (sauf si vos chaînes ne sont pas valides, mais dans ce cas, vous voulez que l'exception vous alerte).
usr

Réponses:


609

Étant donné un tableau, vous pouvez utiliser la Array.ConvertAllméthode :

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

Merci à Marc Gravell d'avoir souligné que le lambda peut être omis, ce qui donne une version plus courte illustrée ci-dessous:

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

Une solution LINQ est similaire, sauf que vous auriez besoin de l' ToArrayappel supplémentaire pour obtenir un tableau:

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

4
Agréable. Je ne connaissais pas celui-là. +1
dépensé

Le code IL que cela génère est en fait inférieur à la réponse de Simon Fox, FWIW
Allen Rice

80
En fait, vous n'avez pas besoin du lambda; ConvertAll(arr, int.Parse)suffit
Marc Gravell

1
Lambda est nécessaire dans VB.Net 2010: uArray = Array.ConvertAll (sNums.Split (","), Function (i) UInteger.Parse (i))
BSalita

1
@BSalita Non, dans VB.Net c'estArray.ConvertAll(arr, AddressOf Integer.Parse)
Slai

31

EDIT: pour convertir en tableau

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

Cela devrait faire l'affaire:

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

1
.ToArray () requis pour répondre à la question d'OP
dépensé

2
changez var en int [] et ajoutez .ToArray () si vous en avez besoin en tant que tableau int
Simon Fox

19

Pour éviter les exceptions avec .Parse, voici quelques .TryParsealternatives.

Pour utiliser uniquement les éléments qui peuvent être analysés:

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

Alternatives utilisant 0pour les éléments qui ne peuvent pas être analysés:

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

La deuxième solution: var a = Enumerable.Range(0, arr.Length).Where(i => int.TryParse(arr[i], out i)).ToArray();renvoie juste les indécits 0,1,2, ... au lieu des valeurs réelles. Quelle est la bonne solution ici?
Beetee

Merci @Beetee. Je ne sais pas à quoi je pensais avec ça. Je l'ai remplacé par une autre alternative.
Slai

@Slai: Merci. Mais qu'est-ce que ça fait new int[0]? Quand j'ai du texte, je n'en ai pas 0dans mon tableau ...
Beetee

@Beetee new int[0]est un tableau int vide. Les deux premiers exemples ignorent les valeurs qui ne peuvent pas être analysées, et les deux derniers exemples utilisent 0pour les valeurs qui ne peuvent pas être analysées.
Slai

@Slai: Ah maintenant je comprends. Je l'ai mélangé avec new int[] {0}. THX.
Beetee

12

vous pouvez simplement convertir un tableau de chaînes en tableau int en:

var converted = arr.Select(int.Parse)

5
agréable! Je vous remercie. Et dans VB.NetDim converted = arr.Select(addressof Integer.Parse)
Mafu Josh

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

Vous devez vous assurer que vous n'obtenez pas de IEnumerable<int>retour


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.