Reputation: 16013
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
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
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
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
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
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
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));
}
Upvotes: 7
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
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