String Split Utility Method Problem when No delimiters are included
I've got the following method I created which works fine if there actually is the delimiter in question. I want to keep this out of LINQ for now...
e.g.
If I pass in the string "123;322;323" it works great.
But if I only pass in one string value without the delimiter such as "123" it obviously is not going to split it since there is no delimiter. I am just trying to figure out the best way to check and account for this and be able to spit out that one value back in the list
public static List<int> StringToList(string st开发者_JAVA百科ringToSplit, char splitDelimiter)
{
List<int> list = new List<int>();
if (string.IsNullOrEmpty(stringToSplit))
return list;
string[] values = stringToSplit.Split(splitDelimiter);
if (values.Length < 1)
return list;
foreach (string s in values)
{
int i;
if (Int32.TryParse(s, out i))
list.Add(i);
}
return list;
}
UPDATED: This is what I came up with that seems to work but sure is long
public static List<int> StringToList(string stringToSplit, char splitDelimiter)
{
List<int> list = new IntList();
if (string.IsNullOrEmpty(stringToSplit))
return list;
if (stringToSplit.Contains(splitDelimiter.ToString()))
{
string[] values = stringToSplit.Split(splitDelimiter);
if (values.Length <= 1)
return list;
foreach (string s in values)
{
int i;
if (Int32.TryParse(s, out i))
list.Add(i);
}
}
else if (stringToSplit.Length > 0)
{
int i;
if(Int32.TryParse(stringToSplit, out i))
list.Add(i);
}
return list;
}
Change this condition:
if (values.Length <= 1)
return list;
To:
if (values.Length <= 0)
return list;
This works because String.Split
will return the original string if it can't find the delimiter:
// stringToSplit does not contain the splitDelimiter
string[] values = stringToSplit.Split(splitDelimiter);
// values is a string array containing one value - stringToSplit
There are a LOT of unnecessary checks for conditions that don't matter to the core logic of the method.
public static List<int> StringToList(string stringToSplit, char splitDelimiter)
{
List<int> list = new IntList();
if (string.IsNullOrEmpty(stringToSplit))
return list;
//this if is not necessary. As others have said, Split will return a string[1] with the original string if no delimiter is found
if (stringToSplit.Contains(splitDelimiter.ToString()))
{
string[] values = stringToSplit.Split(splitDelimiter);
//why check this? if there are no values, the foreach will do nothing and fall through to a return anyway.
if (values.Length <= 1)
return list;
foreach (string s in values)
{
int i;
if (Int32.TryParse(s, out i))
list.Add(i);
}
}
//again, this is rendered redundant due to previous comments
else if (stringToSplit.Length > 0)
{
int i;
if(Int32.TryParse(stringToSplit, out i))
list.Add(i);
}
return list;
}
Try this. You hopefully have some unit tests calling this method to make sure it works...right?
public static List<int> StringToList(string stringToSplit, char splitDelimiter)
{
List<int> list = new IntList();
if (string.IsNullOrEmpty(stringToSplit))
return list;
foreach(var s in stringToSplit.Split(splitDelimiter))
{
int i;
if(int.TryParse(s, out i))
list.Add(i);
}
return list;
}
Personally, I haven't tried out your code, but it looks functional. The Split method should return an array with one element.
Since you say it's not, I believe you, and I would add this to the top of your method:
if (!stringToSplit.Contains(splitDelimiter))
{
int i;
if (Int32.TryParse(stringToSplit, out i))
list.Add(i);
return list;
}
You don't need to account for that situation, as string.Split()
returns an array with a single element when no delimiter is found:
If this instance does not contain any of the strings in separator, the returned array consists of a single element that contains this instance.
See msdn at "Remarks"
Might I suggest an extension method to help you in cases like this in general?
The idea would be to yield return
all results from a collection of strings that can be parsed to a specified type.
First you'd need a delegate to match the signature of your standard TryParse
method:
public delegate bool Parser<T>(string input, out T value);
Then you can write an extension method that takes an instance of this delegate type and enumerates over a collection of strings, parsing everywhere it can:
// Notice: extension methods must belong to a class marked static.
public static class EnumerableParser
{
// modified code to prevent horizontal overflow
public static IEnumerable<T> ParseAll<T>
(this IEnumerable<string> strings, Parser<T> parser)
{
foreach (string str in strings)
{
T value;
if (parser(str, out value))
yield return value;
}
}
}
Now your StringToList
method becomes trivial to implement:
public List<int> StringToList(string stringToSplit, char delimiter)
{
// Notice: since string.Split returns a string[], and string[] implements
// IEnumerable<string>, so the ParseAll extension method can be called on it.
return stringToSplit.Split(delimiter).ParseAll<int>(int.TryParse).ToList();
}
A shorter implementation you might consider.
public static List<int> StringToList(string stringToSplit, char splitDelimiter)
{
int i;
return stringToSplit.Split(splitDelimiter)
.Where(str => int.TryParse(str, out i))
.Select(str => int.Parse(str))
.ToList();
}
Either it must have a delimiter or, it part must have a fixed length or, the string must follow a pattern for repeat behavior.
精彩评论