BMBM
BMBM

Reputation: 16013

Convert comma separated string of ints to int array

I only found a way to do it the opposite way round: create a comma separated string from an int list or array, but not on how to convert input like string str = "1,2,3,4,5"; to an array or list of ints.

Here is my implementation (inspired by this post by Eric Lippert):

    public static IEnumerable<int> StringToIntList(string str)
    {
        if (String.IsNullOrEmpty(str))
        {
            yield break;
        }

        var chunks = str.Split(',').AsEnumerable();

        using (var rator = chunks.GetEnumerator())
        {
            while (rator.MoveNext())
            {
                int i = 0;

                if (Int32.TryParse(rator.Current, out i))
                {
                    yield return i;
                }
                else
                {
                    continue;
                }
            }
        }
    }

Do you think this is a good approach or is there a more easy, maybe even built in way?

EDIT: Sorry for any confusion, but the method needs to handle invalid input like "1,2,,,3" or "###, 5," etc. by skipping it.

Upvotes: 71

Views: 129071

Answers (8)

Victor
Victor

Reputation: 81

Let us assume that you will be reading the string from the console. Import System.Linq and try this one:

int[] input = Console.ReadLine()
            .Split(',', StringSplitOptions.RemoveEmptyEntries)
            .Select(int.Parse)
            .ToArray();

Upvotes: 8

McTrafik
McTrafik

Reputation: 2929

Without using a lambda function and for valid inputs only, I think it's clearer to do this:

Array.ConvertAll<string, int>(value.Split(','), Convert.ToInt32);

Upvotes: 35

dcp
dcp

Reputation: 55434

This is for longs, but you can modify it easily to work with ints.

private static long[] ConvertStringArrayToLongArray(string str)
{
    return str.Split(",".ToCharArray()).Select(x => long.Parse(x.ToString())).ToArray();
}

Upvotes: 2

ZombieSheep
ZombieSheep

Reputation: 29953

--EDIT-- It looks like I took his question heading too literally - he was asking for an array of ints rather than a List --EDIT ENDS--

Yet another helper method...

private static int[] StringToIntArray(string myNumbers)
{
    List<int> myIntegers = new List<int>();
    Array.ForEach(myNumbers.Split(",".ToCharArray()), s =>
    {
        int currentInt;
        if (Int32.TryParse(s, out currentInt))
            myIntegers.Add(currentInt);
    });
    return myIntegers.ToArray();
}

quick test code for it, too...

static void Main(string[] args)
{
    string myNumbers = "1,2,3,4,5";
    int[] myArray = StringToIntArray(myNumbers);
    Console.WriteLine(myArray.Sum().ToString()); // sum is 15.

    myNumbers = "1,2,3,4,5,6,bad";
    myArray = StringToIntArray(myNumbers);
    Console.WriteLine(myArray.Sum().ToString()); // sum is 21

    Console.ReadLine();
}

Upvotes: 7

SLaks
SLaks

Reputation: 887365

You should use a foreach loop, like this:

public static IEnumerable<int> StringToIntList(string str) {
    if (String.IsNullOrEmpty(str))
        yield break;

    foreach(var s in str.Split(',')) {
        int num;
        if (int.TryParse(s, out num))
            yield return num;
    }
}

Note that like your original post, this will ignore numbers that couldn't be parsed.

If you want to throw an exception if a number couldn't be parsed, you can do it much more simply using LINQ:

return (str ?? "").Split(',').Select<string, int>(int.Parse);

Upvotes: 87

badbod99
badbod99

Reputation: 7526

This has been asked before. .Net has a built-in ConvertAll function for converting between an array of one type to an array of another type. You can combine this with Split to separate the string to an array of strings

Example function:

 static int[] ToIntArray(this string value, char separator)
 {
     return Array.ConvertAll(value.Split(separator), s=>int.Parse(s));
 }

Taken from here

Upvotes: 7

Jon Skeet
Jon Skeet

Reputation: 1500165

If you don't want to have the current error handling behaviour, it's really easy:

return text.Split(',').Select(x => int.Parse(x));

Otherwise, I'd use an extra helper method (as seen this morning!):

public static int? TryParseInt32(string text)
{
    int value;
    return int.TryParse(text, out value) ? value : (int?) null;
}

and:

return text.Split(',').Select<string, int?>(TryParseInt32)
                      .Where(x => x.HasValue)
                      .Select(x => x.Value);

or if you don't want to use the method group conversion:

return text.Split(',').Select(t => t.TryParseInt32(t)
                      .Where(x => x.HasValue)
                      .Select(x => x.Value);

or in query expression form:

return from t in text.Split(',')
       select TryParseInt32(t) into x
       where x.HasValue
       select x.Value;

Upvotes: 82

mqp
mqp

Reputation: 71937

I don't see why taking out the enumerator explicitly offers you any advantage over using a foreach. There's also no need to call AsEnumerable on chunks.

Upvotes: 1

Related Questions