'Substring Length cannot be less than zero
I'm separating a string by first name and last name.
I equate the last word to the last name. I equate the remainder to the firstname.
This string can be empty or null. I'm checking for null return.
but in case the string is empty I get the following error.
or I get an error when only the name. for example; string test = "Jack";
How can I do this in a single line without adding another "if else" control to the code?
https://dotnetfiddle.net/7lr07G
[System.ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length]
at System.String.Substring(Int32 startIndex, Int32 length)
Solution 1:[1]
The problem is test.LastIndexOf(" ") which returns -1 if there is no space in test. Have a look at MSDN - String.Substring
You can use String.Contains
var firstname = !string.IsNullOrEmpty(test) && test.Contains(" ")
? test.Substring(0, test.LastIndexOf(" "))
: string.IsNullOrEmpty(test) ? string.Empty : test;
var lastname = !string.IsNullOrEmpty(test) && test.Contains(" ")
? test.Split(' ').Last()
: string.Empty;
to check if there is a space in test.
I recommend using String.IsNullOrEmpty instead of test != null.
Solution 2:[2]
Try with this:
//string test = "Jack ";
//string test = "Jack";
string test = "Jack Nelsson";
var firstname = string.Empty;
var lastname = string.Empty;
if (!string.IsNullOrEmpty(test))
{
var index = test.LastIndexOf(" ");
if (index < 0 || index >= test.Length - 1)
{
firstname = test.TrimEnd();
}
else
{
firstname = test.Substring(0, index);
lastname = test.Substring(index + 1);
}
}
Console.WriteLine(firstname);
Console.WriteLine(lastname);
By default, we set string.Empty. If test has a string, we search last whitespace and store in a variable to use later.
If no namespace found: set firstname to all text. If whitespace found at the end of the string: set firstname to all text without ending spaces. We need to check this case because substring with index+1 fail in this case. In other case, split the string in that point.
Solution 3:[3]
I prefer to use IndexOf as little as possible, because I always end up confusing myself with the indices. So here's different approach:
string firstname = "";
string lastname = "";
if (!string.IsNullOrEmpty(name))
{
var parts = name.Split(' ');
lastname = parts[parts.Length-1];
firstname = string.Join(" ", parts.Take(parts.Length-1));
}
It simply splits using space, then makes the last part the last name and join the others as the first name.
EDIT
I just saw Mighty Badaboom's solution and was inspired by the use of Last. Here's a version with even fewer integers involved:
string firstname = "";
string lastname = "";
if (!string.IsNullOrEmpty(name))
{
var parts = name.Split(' ');
lastname = parts.Last();
firstname = string.Join(" ", parts.SkipLast(1));
}
SkipLast requires .NET standard 2.1. If on older standard you can go for:
firstname = string.Join(" ", parts.Reverse().Skip(1).Reverse());
Solution 4:[4]
Try this one:
string test = "Jack Daniels";
var firstname = string.IsNullOrEmpty(test)
? string.Empty
: (test.Contains(" ") ? (test.Substring(0, test.LastIndexOf(" "))).Trim() : test);
var lastname = string.IsNullOrEmpty(test)
? string.Empty
: (test.Contains(" ") ? (test.Substring(test.LastIndexOf(" ")).Trim()) : string.Empty);
Console.WriteLine("firstname>>" + firstname);
Console.WriteLine("lastname>>" + lastname);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Victor |
| Solution 3 | |
| Solution 4 | Abdul Rahman A |
