6

2 days ago, there was a question related to string.LastIndexOf(String.Empty) returning the last index of string:

Do C# strings end with empty string?

So I thought that; a string can always contain string.empty between characters like:

"testing" == "t" + String.Empty + "e" + String.Empty +"sting" + String.Empty;

After this, I wanted to test if String.IndexOf(String.Empty) was returning 0 because since String.Empty can be between any char in a string, that would be what I expect it to return and I wasn't wrong.

string testString = "testing";
int index = testString.LastIndexOf(string.Empty); // index is 6
index = testString.IndexOf(string.Empty); // index is 0

It actually returned 0. I started to think that if I could split a string with String.Empty, I would get at least 2 string and those would be String.Empty and rest of the string since String.IndexOf(String.Empty) returned 0 and String.LastIndexOf(String.Empty) returned length of the string.. Here is what I coded:

string emptyString = string.Empty;
char[] emptyStringCharArr = emptyString.ToCharArray();
string myDummyString = "abcdefg";
string[] result = myDummyString.Split(emptyStringCharArr);

The problem here is, I can't obviously convert String.Empty to char[] and result in an empty string[]. I would really love to see the result of this operation and the reason behind this. So my questions are:

  1. Is there any way to split a string with String.Empty?

  2. If it is not possible but in an absolute world which it would be possible, would it return an array full of chars like [0] = "t" [1] = "e" [2] = "s" and so on or would it just return the complete string? Which would make more sense and why?

Community
  • 1
  • 1
Pabuc
  • 5,528
  • 7
  • 37
  • 52

6 Answers6

2

You will always get an Index of 0 when you look for String.Empty in any String, because it's the definition of String.IndexOf(String.Empty) you should have a look at the MSDN, where it says:

"The zero-based index position of value if that string is found, or -1 if it is not. If value is String.Empty, the return value is 0."

Directed to your second Question:

I think you can Split a String with an Empty String by doing something like this in your code:

String test = "fwewfeoj";
test.Split(new String[] { String.Empty }, StringSplitOptions.None);

By the way: Possible Clone of this answer Why does "abcd".StartsWith("") return true?

Community
  • 1
  • 1
basti
  • 2,649
  • 3
  • 31
  • 46
  • You are stating the obvious, I can see that I would always get 0 for IndexOf(string.empty) yet I'm looking for the reason behind this and trying my best to find it out. – Pabuc Jan 12 '11 at 08:48
  • 1
    Because it's defined in the function that IndexOf(String.Empty) _always_ has to return 0. – basti Jan 12 '11 at 08:51
  • He gave you the reason. It returns 0 when String.Empty is passed in as a special-case return. – Rob Jan 12 '11 at 08:52
  • i still can't figure out why. There must be a reason. – Pabuc Jan 12 '11 at 09:15
2

Yes, you can split any string with string .Empty

 string[] strArr = s.Split(string.Empty.ToCharArray());
AsifQadri
  • 2,388
  • 1
  • 20
  • 30
1

Do you really need to split the string, or are you just trying to get all the individual characters?

If so, then a string is also a IEnumerable<char>, and you also have an indexer.

So, what are you actually trying to do?

And no, you can't call the split methods with string.Empty or similar constructs.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • 1
    Since "ab" == "a"+string.empty+"b" I would expect "ab".split(string.empty) to return "a" and "b" and if I could get all Indexes of string.empty in "ab" I would expect it to be 0,1. So MSDN states that indexof(string.empty) would return 0 and lastIndex(string.empty) would return the last index of string. Does it mean that they really check if the incoming parameter is string.empty and return from there or is there any logic behind it? – Pabuc Jan 12 '11 at 08:52
  • 1
    But, "ab" + string.Empty + "c", and then split that, you wouldn't get back those two parts if you could, you would get 3 parts. string.Empty equates to an empty string, hence the name, and you can't really find it after adding it into a string. – Lasse V. Karlsen Jan 12 '11 at 08:54
  • Yes, they really check the incoming parameter. String.Empty is not a special character, it really is _nothing_. It's not found between each character, so splitting on it wouldn't make sense.. If anything it should just return the original string. – Rob Jan 12 '11 at 08:55
  • string.Empty is not nothing. Try : string.Empty == "", it will return true. For me, it's just an alias. When you try testString.IndexOf(string.Empty); you've got the first occurence of "" : none (==> 0). When you try testString.LastIndexOf(string.Empty); you've got the last index of your string (testString.Length -1), the last **possible** index in your string (==> testString[6]). – kerrubin Jan 12 '11 at 09:06
  • Yeah, but those things are hardcoded into the behavior, there's no actual searching involved here. In any case, this whole discussion started with string.Split, which still isn't possible using string.Empty. – Lasse V. Karlsen Jan 12 '11 at 09:07
  • @kerrubin: When I said nothing, I didn't mean it in that sense. It's not returning those values for IndexOf because it finds "", it's because it's hardcoded to do so – Rob Jan 12 '11 at 09:13
  • Why? What specifically is it that you want it to do that you can't do without that support? – Lasse V. Karlsen Jan 12 '11 at 09:16
  • I can't get a string array that each element contains only 1 char of the whole string :) – Pabuc Jan 12 '11 at 09:23
  • Not in one method call, no, but: `var arr = s.Select(c => c.ToString()).ToArray();` However, are you sure you want to do that? Have you thought about diacritics, like "è", might be split into two characters. – Lasse V. Karlsen Jan 12 '11 at 09:42
  • @Rob I said that because, "nothing" is like "null" :) @Pabuc : you can't have directly a string[], but you can make a method to do so. – kerrubin Jan 12 '11 at 09:46
  • Well the main reason of using c# is you can do most of the things with 1 method call :) So yes I would expect to do it with 1 line of code :) Thank you anyways, it was a good brainstorm therapy :) – Pabuc Jan 12 '11 at 09:55
1
string emptyString = string.Empty;
char[] emptyStringCharArr = emptyString.ToCharArray();

This will give you an empty array of chars. This is because String is already an array of chars in memory, and String.Empty has no value.

To break it down further, consider an implementation of .ToCharArray()

private Char[] toCharArray(String value)
{
    var stringLength = value.Length;
    var returningArray = new char[stringLength];
    for(var i = 0; i < stringLength; i++)
    {
        returningArray[i] = value[i];
    }
    return returningArray;
}

Length of course will be zero, and you will return an empty char array. Of course this isn't the exact implementation, but you can see how and why it's returning nothing (and therefore isn't splitting on the string as you're expecting it to)

It's not an array with a single element String.Empty, because that doesn't really make sense. When you try to split on an empty array, it doesn't know how or what to split on, so you're given back the original string.

As for why it returns 0 by default, consider:

private int IndexOf(String value, String searchFor)
{
    for(var i = 0; i < value.Length; i++)
    {
        if(value.Substring(i, searchFor.Length) == searchFor)
        {
            return i;
        }
    }
    return -1;
}
private int LastIndexOf(String value, String searchFor)
{
    var searchLength = searchFor.Length;
    for(var i = value.Length - searchFor.Length; i >= 0; i--)
    {
        if(value.Substring(i, searchLength) == searchFor)
            return i;
    }
    return -1;
}

String.SubString(x, 0) will ALWAYS return String.Empty, regardless of what's passed in (even String.Empty). For this reason it's much faster to add a check and return 0 regardless (as it would even if it ran the loop).

Rob
  • 26,989
  • 16
  • 82
  • 98
  • Yes I clearly know why (string.empty).toCharArray doesn't work :) But why would they return 0 or return String.Length for IndexOf(string.empty) and LastIndexOf(string.empty)? What is the logic? What if they don't? – Pabuc Jan 12 '11 at 09:18
  • Editted to show what really happens (not exact code obviously.. just the logic of the function) when you call it. – Rob Jan 12 '11 at 09:28
0

Since String.Empty is just an empty string, so if you do:

var s = "part1" + string.Empty + "part2";

this will result in exactly the same string as:

var s = "part1" + "part2";

the first syntax will not insert a magic empty string between the two parts.

That IndexOf returns 0, is by definition, not because there is some magic empty string between characters.

I cannot think of a logic way to split a string, by an empty string. What should it return? When using an empty string as an argument to the string.Split method, it will be ignored. If it was the only separator to use, the string will be returned unsplit.

GvS
  • 52,015
  • 16
  • 101
  • 139
  • I would expect it to work as ToCharArray and give me a string array instead. It doesn't throw exception if you try it like the way I do yet it also doesn't split with string.empty :) – Pabuc Jan 12 '11 at 08:57
0

you could also say

"testing" == string.Empty + string.Empty + string.Empty + ... + "t" +  string.Empty + string.empty + "esting";

So actually you could place an endless array of string.empty between each character.

So I think 1 not possible 2 none, it just doens't make sense...

tourist
  • 11
  • 2