# Getting a substring of a delimited string

I have some underscore-delimited strings like abc_def_ghi. I would like to get a substring out of the string made of one or more delimited substrings, so that if I call:

getUnderscoreSubstring("abc_def_ghi",2)


then I get:

abc_def


This is the C# code I'm using:

public string getUnderscoreSubstring(string fullStr,int substringCount)
{
string[] splitArray = fullStr.Split('_');
if (substringCount>splitArray.Count())
{
return null;
}
else
{
string output = "";
for(int c=0;c<substringCount;c++)
{
output += splitArray[c];
if (c<substringCount-1)
{
output += "_";
}
}
return output;
}
}


I'm wondering if there's a simpler way to rewrite this, possibly using extension methods.

• Please clarify your motivation. What do you want to be the result of getUnderscoreSubstring("__abc_def_ghi", 2), and why? Apr 30 '15 at 23:52
• I don't have any values like that in the data set; they would be excluded from these function calls by prior validation. Apr 30 '15 at 23:57

Yes, you can definitely simplify this.

public string GetSubstring(string input, int count, char delimiter)
{
return string.Join(delimiter.ToString(),
input.Split(delimiter).Take(count));
}


Calling it is as easy as GetSubstring(input, 2, '_')

What does it do?

• Split the input string by the delimiter
• Take the amount of substrings you want
• Glue the selected substrings together with your delimiter

Very short and sexy!

This doesn't take the substringCount > splitArray.Count() in account but you can easily add that yourself: just split up the oneliner and add the appropriate check.

• Use .Length instead of .Count() when possible: the former will always be an O(1) operation, the latter sometimes an O(n). It won't make a difference here since an array implements ICollection<T> (and will use this optimization) but it's a good practice to observe.
• Returning null is typically avoided for good reasons, consider an empty string or exception instead (don't go for the exception in this case).
• I prefer to explicitly use string.Empty rather than an empty string to avoid confusion.
• Write your variable names in full -- nobody is helped by abbreviating them.
• Use a StringBuilder to concatenate in a loop to avoid unnecessary string object creating.
• Leave some space in your code, it will read more fluently.

Basically, you want to find the substringCountth occurrence of '_' in the string, and return all the characters before that.

Basing on the code from https://stackoverflow.com/a/11363213/1108056

private int IndexOfNth(string str, char c, int n)
{
int index = -1;
while (n-- > 0)
{
index = str.IndexOf(c, index + 1);
if (index == -1) break;
}
return index;
}

public string GetSubstring(string input, int count, char delimiter)
{
return input.Substring(0,IndexOfNth(input, delimiter, count));
}