324

I have an array of integers in string form:

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

I need to an array of 'real' integers to push it further:

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

I tried to cast int and it of course failed:

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

I can do next:

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

or

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

but both looks ugly.

Is there any other ways to complete the task?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
  • 3
    What's wrong with simply iterating through one collection, converting the value, and the adding it to the second? Seems pretty clear in intention to me. – Ed S. Aug 19 '09 at 00:11
  • 1
    Otherwise, http://msdn.microsoft.com/en-us/library/73fe8cwf.aspx – Ed S. Aug 19 '09 at 00:12
  • 1
    Just FYI, I'm using this question here: http://stackoverflow.com/questions/1297325/can-i-compare-il-code-to-determine-which-technique-is-faster-or-better – Allen Rice Aug 19 '09 at 00:49
  • Related: [convert string-array to int-array, fastest](http://stackoverflow.com/questions/3083529/convert-string-to-int/3083567#3083567) – Marc Gravell Jun 21 '10 at 10:07
  • 1
    TryParse is not faster (except if your strings are invalid, but in that case you *want* the exception to alert you). – usr Jun 09 '12 at 18:34
  • I'm a little curious why my answer was unaccepted after ~3 years. In any case I added a LINQ solution just to satisfy the original question, which was very similar to the `ConvertAll` approach. – Ahmad Mageed Jun 09 '12 at 18:36
  • @AhmadMageed: o_O Oops, indeed, sorry. I was reviewing my answer and did that by mistake :) – abatishchev Jun 09 '12 at 19:00
  • @abatishchev, yes but you don't have exceptions in your case. If you had exceptions, you couldn't have converted Parse to TryParse without a change in behavior. And in the absence of exceptions it is not faster. – usr Jun 09 '12 at 19:37

6 Answers6

706

Given an array you can use the Array.ConvertAll method:

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

Thanks to Marc Gravell for pointing out that the lambda can be omitted, yielding a shorter version shown below:

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

A LINQ solution is similar, except you would need the extra ToArray call to get an array:

int[] myInts = arr.Select(int.Parse).ToArray();
Ahmad Mageed
  • 94,561
  • 19
  • 163
  • 174
  • 5
    Nice. Didn't know that one. +1 – spender Aug 19 '09 at 00:17
  • The IL code this generates is actually less than Simon Fox's answer, FWIW – Allen Rice Aug 19 '09 at 00:21
  • 86
    Actually, you don't need the lambda; `ConvertAll(arr, int.Parse)` is sufficient – Marc Gravell Dec 08 '10 at 13:35
  • 1
    Lambda is needed in VB.Net 2010: uArray = Array.ConvertAll(sNums.Split(","), Function(i) UInteger.Parse(i)) – BSalita Jan 15 '12 at 15:24
  • I did this to convert an `int[]` array to an `String` array: `Array.ConvertAll(chaptersIds, Convert.ToString)` Pretty nice! :D – Leniel Maccaferri Feb 14 '13 at 20:21
  • 1
    @BSalita No, in VB.Net it's `Array.ConvertAll(arr, AddressOf Integer.Parse)` – Slai May 03 '16 at 18:03
  • you don't check for errors, it is not a good practice to assume that all strings are well formatted even if you think so, many things can go wrong and you end up with an exception that there is an un-parsable string – Amr Alaa Feb 22 '19 at 12:08
  • @AmrAlaa congrats, you're the first downvoter :) Seriously though, the original question shows an approach using TryParse, so if anyone wants to check for errors that's one option, with some drawbacks. I don't disagree with you; error checking is important, but I feel the answer was sufficient for the question and did not get exhaustive about error checking. StackOverflow should point you to a solution, but that doesn't mean it should be copy-pasted into our projects without reflection and enhancements as needed. – Ahmad Mageed Feb 22 '19 at 18:45
35

EDIT: to convert to array

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

This should do the trick:

var asIntegers = arr.Select(s => int.Parse(s));
Simon Fox
  • 10,409
  • 7
  • 60
  • 81
30

To avoid exceptions with .Parse, here are some .TryParse alternatives.

To use only the elements that can be parsed:

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 }

or

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

Alternatives using 0 for the elements that can't be parsed:

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

or

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);
Slai
  • 22,144
  • 5
  • 45
  • 53
  • The second solution: `var a = Enumerable.Range(0, arr.Length).Where(i => int.TryParse(arr[i], out i)).ToArray();` just returns the indeces 0,1,2,... instead of the real values. What's the right solution here? – Beetee Jul 10 '17 at 11:20
  • Thanks @Beetee. Not sure what I was thinking with that. I replaced it with another alternative. – Slai Jul 10 '17 at 12:14
  • @Slai: Thanks. But what does `new int[0]`? When I have text, I don't get a `0` in my array... – Beetee Jul 11 '17 at 08:13
  • @Beetee `new int[0]` is an empty int array. The first two examples skip values that can't be parsed, and the last two examples use `0` for values that can't be parsed. – Slai Jul 11 '17 at 11:12
  • @Slai: Ah now I get it. I mixed it up with `new int[] {0}`. Thx. – Beetee Jul 11 '17 at 13:10
  • if you're using VB.net, the query syntax won't work. You'll need to use the method syntax. arr.Where(Function(s) Integer.TryParse(s, i)).Select(Function(s) i).ToList() – an phu Jun 13 '19 at 19:48
  • @anphu where might not be needed in VB as it has the safe [`Val`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.conversion.val) function `(From s In arr Select Int(Val(s))).ToArray`, with optional `Where isnumeric(s)` if needed – Slai Jun 13 '19 at 21:36
14

you can simply cast a string array to int array by:

var converted = arr.Select(int.Parse)
A.Dara
  • 784
  • 10
  • 23
4
var asIntegers = arr.Select(s => int.Parse(s)).ToArray(); 

Have to make sure you are not getting an IEnumerable<int> as a return

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Rob
  • 1,320
  • 1
  • 8
  • 14
3
var list = arr.Select(i => Int32.Parse(i));
sepp2k
  • 363,768
  • 54
  • 674
  • 675