Trim space in <list>string C# - c#

I am working on an application where I have multiple ID in a string that I passed from my view separated by a ';'.
So this is what it looks like "P171;P172".
if (ModelState.IsValid)
{
hiddenIDnumber= hiddenIDnumber.Trim();
List<string> listStrLineElements = hiddenIDnumber.Split(';').ToList();
foreach (string str in listStrLineElements)
The problem is, when I split my hiddenIDnumber, even if I have two numbers, I get a count of 3 and "" is returned (which I believe is an empty space).
When I use a breakpoint i get "P171","P172" AND "".
This is causing my program to fail because of my FK constraints.
Is there a way to "overcome this and somehow "trim" the space out?

Use another overload of string.Split whih allows you to ignore empty entries. For example:
List<string> listStrLineElements = hiddenIDnumber
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.ToList();

I would say that one way to do this would be to use String Split Options. With String.Split there is an overload that takes two arguments, i.e. it would be like
myString.Split(new [] {';'}, StringSplitOptions.RemoveEmptyEntries);
This should prevent any entries in your array that would only be an empty string.

var listStrLineElements = hiddenIDnumber.Split(new char[]{';'}, StringSplitOptions.RemoveEmptyEntries);
Use the parameter StringSplitOptions.RemoveEmptyEntries to automatically remove empty entries from the result list.

You can try:
IList<string> listStrLineElements = hiddenIDnumber.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
I prefer this over new [] { ';' } for readability, and return it to an interface (IList<string>).

You will end up with the number of ;s plus one when you split. Since your comment mentions you have 2 ;s, you will get 3 in your list: before the first semicolon, between the first and the second, and after the second. You are not getting an empty space, you are getting a string.Empty because you have nothing after the last ;
if (ModelState.IsValid)
{
hiddenIDnumber= hiddenIDnumber.Trim(";");
List<string> listStrLineElements = hiddenIDnumber.Split(';').ToList();
foreach (string str in listStrLineElements)
This way you get rid of the ; at the end before you split, and you don't get an empty string back.

Related

Getting an extra entry in array for each newline

For the following code...
IEnumerable<string> items=searchterms.Trim().Split(Environment.NewLine.ToCharArray());
foreach (var item in items) {
I'm getting an item of length 0 in-between each searchterm item. I've used similar code elsewhere and not run into this, so not sure why it's happenning now. What do I need to add here to get rid of these extra entries? i.e. so that the number of items matches the number of terms in the input. I have a work-around (skip items with length 0), but it's an annoyance that the numbers don't match, and I would like to fix it for displaying progress purposes. i.e. item i+1 of items.count.
P.S. this is in Xamarin Forms on UWP.
thanks,
Donald.
The problem is that you split by a char array of { '\r', '\n' } which means either symbol is regarded as a separator, not the whole sequence of "\r\n", i.e. there is an empty string in "\r\n" in between.
To split by the whole sequence only use a string array of one element
IEnumerable<string> items = searchterms.Trim().Split(new string[] { Environment.NewLine, }, StringSplitOptions.None);
This will not produce an empty item unless there are to consecutive "\r\n" in the string. If you also want to remove empty items in such case you can use the RemoveEmptyEntries string split option.
IEnumerable<string> items = searchterms.Trim().Split(new string[] { Environment.NewLine, }, StringSplitOptions.RemoveEmptyEntries);
Since the newline is composed from 2 characters (on most systems anyway, \r and \n), you may be getting an extra empty string as the string between these characters.
Try this:
IEnumerable<string> items=searchterms.Trim().Split(new string[] {Environment.NewLine}, StringSplitOptions.None);
foreach (var item in items) {

Split string and exclude last split

Is there anyway for me to split a string and exclude the last split?
My data looks like this: data1,data2,data3, and so if I split the element the last element in the array will be empty, so I would just prefer to exclude it from the split.
Right now I have this:
serialNumbers = delimitedSerials.ToString().Split(',');
Granted I know I can just leave it and in my for loop just know to skip the last element, but was wondering if there was a simple way to just exclude it at the time of splitting.
you can split it using the StringSplitOptions parameter:
data.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
Below code has a Linq where clause to exclude the empty data
string input ="data1,data2,data3,";
var output = input.Split(',').Where(value => !string.IsNullOrEmpty(value));
foreach(string data in output)
Console.WriteLine(data);

Confusing error when splitting a string

I have this line of code:
string[] ids = Request.Params["service"].Split(",");
the values in Request.Params["service"] are: "1,2"
Why am I getting:
Error 1 The best overloaded method match for 'string.Split(params char[])' has some invalid arguments
Error 2 Argument 1: cannot convert from 'string' to 'char[]'
This makes no sense to me....
The error happens on everything to the right of the equal sign
You need to pass a character (System.Char), not a string:
string[] ids = Request.Params["service"].Split(',');
There is no overload to String.Split that takes a params string[] or a single string, which is what would be required to make your code work.
If you wanted to split with a string (or multiple strings), you would need to use a string[] and specify splitting options:
string[] ids = Request.Params["service"].Split(new[]{","}, StringSplitOptions.None);
You have to use the overload with the params Char[]:
string[] ids = Request.Params["service"].Split(',');
As others said on here your provided (",") the double quote denotes a string and the Split function accepts a Character array or char[]. Use (',') , the single quote denotes a character. You can also pass along StringSplitOptions which if you happen to get empty values in your string[] it requires a char[] to be passed along with it, illustrated below.
string splitMe = "test1,test2,";
string[] splitted1 = splitMe.Split(',');
string[] splitted2 = splitMe.Split(new char[]{','},StringSplitOptions.RemoveEmptyEntries);
//Will be length 3 due to extra comma
MessageBox.Show(splitted1.Length.ToString());
//Will be length 2, Removed the empty entry since there was nothing after the comma
MessageBox.Show(splitted2.Length.ToString());
In the line
Request.Params["service"].Split(",");
You're splitting by "," instead of ','
The .Split() method takes an array of characters, not a string

Why does C# split give me an array ending in an empty line?

I have the following expression:
"<p>What ?</p>\n<pre>Starting Mini</pre>"
When I perform a split as follows:
var split = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.None);
Then it gives me three entries:
"<p>What ?</p>\n"
"Starting Mini"
""
Why does it give an empty line as the third entry and how can I avoid this?
The "why" is simply: the input (if you don't remove empty entries) will always "split" at any occurrence of the separator(s), so if the separator(s) appear n times in the string, then the array will be n+1 long. In particular, this essentially lets you know where they occurred in the original string (although when using multiple separators, it doesn't let you know which appeared where).
For example, with a simple example (csv without any escaping etc):
string[] arr = input.Split(','); // even if something like "a,b,c,d,"
// which allows...
int numberOfCommas = arr.Length - 1;
string original = string.Join(",", arr);
The fix is, as already mentioned, to use RemoveEmptyEntries.
Use StringSplitOptions.RemoveEmptyEntries instead to remove empty string in list
var split = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.RemoveEmptyEntries);
You get this behaviour as specified from Microsoft:
"Adjacent delimiters yield an array element that contains an empty string ("")."
So since you have the last pre you get the last empty array element
Mailou, instead of giving 'StringSplitOptions.None' try 'StringSplitOptions.RemoveEmptyEntries'. It removes the the empty lines.
The reason you are getting this behaviour is that your one of the delimeter </pre> happens to exist at the end of the string.
You may see: string.Split - MSDN
...a delimiter is found at the beginning or end of this instance, the
corresponding array element contains Empty
To overcome this:
Use StringSplitOptions.RemoveEmptyEntries instead of StringSplitOptions.None
StringSplitOptions.RemoveEmptyEntries - MSDN
The return value does not include array elements that contain an empty
string
var split = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.RemoveEmptyEntries);
You also need to specify the
StringSplitOptions.RemoveEmptyEntries enumerator.
The split string[] values not include any empty string by using StringSplitOptions.RemoveEmptyEntries
var split = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.RemoveEmptyEntries);
Reference: StringSplitOptions Enumeration
You are getting empty line due to
</pre>
You are instructing split function to split by <pre> and </pre>
As result with <pre> you are getting
<p>What ?</p>\n
Starting Mini</pre>
And next result is with </pre> is
<p>What ?</p>\n
Starting Mini
...

StringSplitOptions.RemoveEmptyEntries doesn't work as advertised

I've come across this several times in the past and have finally decided to find out why.
StringSplitOptions.RemoveEmptyEntries would suggest that it removes empty entries.
So why does this test fail?
var tags = "One, Two, , Three, Foo Bar, , Day , ";
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim());
tagsSplit.ShouldEqual(new string[] {
"One",
"Two",
"Three",
"Foo Bar",
"Day"
});
The result:
Values differ at index [2]
Expected string length 5 but was 0. Strings differ at index 0.
Expected: "Three"
But was: <string.Empty>
So it fails because instead of "Three", we have an empty string – exactly what StringSplitOptions.RemoveEmptyEntries should prevent.
Most likely because you change the string after the split. You trim the values after splitting them, RemoveEmptyEntries doesn't consider the string " " empty.
The following would achieve what you want, basically creating your own strip empty elements:
var tagsSplit = tags.Split(',').
Select(tag => tag.Trim()).
Where( tag => !string.IsNullOrEmpty(tag));
Adjacent delimiters yield an array element that contains an empty
string (""). The values of the StringSplitOptions enumeration specify
whether an array element that contains an empty string is included in
the returned array.
" " by definition is not empty (it is actually whitespace), so it is not removed from resulting array.
If you use .net framework 4, you could work around that by using string.IsNullOrWhitespace method
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(s => s.Trim());
RemoveEmptyEntries do not means space.
Your input string include many "space". You should notice that "space" is not empty. In computer, space is a special ASCII code. so the code:
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim());
means:
Split the input by ',' and remove empty entry, not include space. So
you got an array with some space elements.
Then you do trim for each of elements. The space elements become to empty.
That's why you got it.
In .NET 5, they added StringSplitOptions.TrimEntries.
Since StringSplitOptions has the [System.Flags] attribute, it means you can write
var splitResult = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
When both RemoveEmptyEntries and TrimEntries are specified, it removes both empty values and values which only contain whitespace, whilst trimming all the remaining values.
Try
var tagsSplit = tags.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
This will spit by comma and space, and eliminate empty strings.
I've searched also for a clean way to exclude whitespace-entries during a Split, but since all options seemed like some kind of workarounds, I've chosen to exclude them when looping over the array.
string[] tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tag in tagsSplit.Where(t => !string.IsNullOrWhiteSpace(t))) { }
I think this looks cleaner and - as a bonus - .Split(...).ToArray() may be ommited.
Of course, it is an option only when you may loop just after split and do not have to store entries for later use.
As this is a very common need, I went ahead and wrapped the most popular answer in a string extension method:
public static IEnumerable<string> Split_RemoveWhiteTokens(this string s, params char[] separator)
{
return s.Split(separator).
Select(tag => tag.Trim()).
Where(tag => !string.IsNullOrEmpty(tag));
}
To split on ',' as the other examples, use like this:
var result = yourString.Split_RemoveWhiteTokens(',')
Note that the return type is IEnumerable, so you can do additional LINQ queries directly on the return result. Call .ToList() if you want to cast the result to a list.
By EmptyEntries it means a case where two delimiters are directly next to each other with nothing in between. Without using this option, it will print a blank line to represent this delimitation. If you use the "RemoveEmptyEntries" option it will not show the delimitation unless there is actually something between the delimiters. A blank space counts as something between the delimiters. If you tried:
One, Two,, Three,
You should find that RemoveEmptyEntries eliminates the delimitation between the two commas and goes straight from Two to Three.
var tagsSplit = tags.Split(',')
.Where(str => str != String.IsNullOrWhiteSpace(str))
.Select(s => s.Trim());

Categories