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.
2 Answers 2
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.
Now, some comments about your code:
- 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 implementsICollection<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 substringCount
th 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));
}
getUnderscoreSubstring("__abc_def_ghi", 2)
, and why? \$\endgroup\$