Tutorial :String Split Utility Method Problem when No delimiters are included



Question:

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 stringToSplit, 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;      }  


Solution:1

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


Solution:2

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  


Solution:3

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


Solution:4

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"


Solution:5

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


Solution:6

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


Solution:7

Either it must have a delimiter or, it part must have a fixed length or, the string must follow a pattern for repeat behavior.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »