Why does "abcd".StartsWith("") return true?
Asked Answered
A

11

89

Title is the entire question. Can someone give me a reason why this happens?

Architect answered 28/9, 2008 at 8:59 Comment(0)
P
168

Yes - because it does begin with the empty string. Indeed, the empty string logically occurs between every pair of characters.

Put it this way: what definition of "starts with" could you give that would preclude this? Here's a simple definition of "starts with" that doesn't:

"x starts with y if the first y.Length characters of x match those of y."

An alternative (equivalent) definition:

"x starts with y if x.Substring(0, y.Length).Equals(y)"

Physicality answered 28/9, 2008 at 9:4 Comment(12)
x starts with y if x.Substring(0,y.Length).Equals(y) if and only if y.Length > 0Snowstorm
Yup, you could indeed explicitly exclude this case. It's a pretty inelegant definition though, isn't it?Physicality
Jon, basically your statement requires "y.Length <= x.Length && " or it'll throw an IndexOutOfRangeException ;)Diggins
True. It also requires them to be non-null, too... but I'd say both of these add to the accuracy while taking away from the spirit of the simple definition :)Physicality
I'll agree with Jon's definition exception that the semantics of StartsWith() is done a disservice in the 'mootness' of the result if string.Empty does not yield an argument exception. For every non-null string x, x.StartsWith(string.Empty) will be true. So, what's the point? This creates a gaping hole ... and looks like a common ancestor for hard-to-detect bugs and security holes. As a developer trying to validate an experience, you loose the certainty of saying that the chances of an input being equal to my hidden value is low.Outward
Infinite occurrences of the empty string occur between every pair of characters.Yusem
Yeah, it's just like putting a zero before a number — It doesn't change the value yet it still exists.Weisshorn
Jon could you explain with an exampleGodsend
@Deepak: An example of what, exactly?Physicality
While in set theory it's true that a set of characters contains the empty set of characters, in practice this notion doesn't really map well to the String class and it's more common use-cases. It's almost certainly a logical error to ask a string if it starts with an empty string, therefore it's more appropriate, in my judgment anyway, for startsWith() and the like to throw an IllegalArgumentException indicating the irrelevance.Backrest
@Weisshorn Except, putting a zero before a number does sometimes change the value; Compilers and number parsing algorithms, for example, will interpret numbers differently depending on the largest digit. Prefixing it with a 0 may cause the number to be interpreted as octal or binary, leading to incorrect results and hard to find bugs.Zoila
@TomLint The analog wasn't about programming language syntax, but standard western numerical notation.Bulbiferous
L
48

I will try to elaborate on what Jon Skeet said.

Let's say x, y and z are strings and + operator is in fact concatenation, then:

If we can split z to write z = x + y that means that z starts with x. Because every string z can be split to z = "" + z it follows that every string starts with "".

So, because ("" + "abcd") == "abcd" it follows that "abcd" starts with ""

Lurid answered 10/10, 2008 at 22:3 Comment(0)
W
20

I'll start with a related fact that is easier to understand.

The empty set is a subset of every set.

Why? The definition of subset states that A is a subset of B if every element of A is an element of B. Conversely, A is not a subset of B if there is an element of A that is not an element of B.

Now fix a set B. I'll establish that the empty set is a subset of B. I'll do this by showing that it is not the case that the empty set is not a subset of B. If the empty set were not a subset of B then I could find an element of the empty set that is not in B. But the empty set does not have any elements and thus I can not find an element that is not in B. Therefore, it is not the case that the empty set is not a subset of B. Thus, the empty set must be a subset of B.

Any string starts with the empty string.

First, we must agree on our definition of starts with. Let s and t be strings We say that s starts with t if s.Length >= t.Length and the first t.Length characters of t match those of s. That is, s.Length >= t.Length and for every Int32 index such that 0 <= index < t.Length, s[index] == t[index] is true. Conversely, we would say that s does not start with t if the statement

s.Length < t.Length or s.Length >= t.Length and there is an Int32 index such that 0 <= index < t.Length and s[index] != t[index]

is true. In plain English, s is shorter than t, or, if not, there is a character in t not matching the character as the same position in s.

Now fix a string s. I'll establish that s starts with the empty string. I'll do this by showing that it is not the case that s does not start with the empty string. If s does not start with the empty string then s.Length < String.Empty.Length or s.Length >= String.Empty.Length and there is an Int32 index such that 0 <= index < String.Empty.Length. But s.Length >= 0 and String.Empty.Length is equal to zero so it is impossible for s.Length < String.Empty.Length to be true. Similarly, since ``String.Empty.Lengthis equal to zero, there is noInt32 indexsatisfying0 <= index < String.Empty.Length`. Therefore

s.Length < String.Empty.Length or s.Length >= String.Empty.Length and there is an Int32 index such that 0 <= index < String.Empty.Length

is false. Therefore, it is not the case that s does not start with the empty string. Thus, s must start with the empty string.

The following is an implementation of starts with coded as an extension to string.

public static bool DoStartsWith(this string s, string t) {
    if (s.Length >= t.Length) {
        for (int index = 0; index < t.Length; index++) {
            if (s[index] != t[index]) {
                return false;
            }
        }
        return true;
    }
    return false;
}

The above two bolded facts are examples of vacuously true statements. They are true by virtue of the fact that the statements defining them (subset and starts with) are universal quantifications over empty universes. There are no elements in the empty set, so there can not be any elements of the empty set not in some other fixed set. There are no characters in the empty string, so there can not be a character as some position in the empty string not matching the character in the same position in some other fixed string.

Water answered 24/12, 2008 at 5:11 Comment(0)
S
17

This method compares the value parameter to the substring at the beginning of this string that is the same length as value, and returns a value that indicates whether they are equal. To be equal, value must be an empty string (Empty), a reference to this same instance, or match the beginning of this instance.

.NET String.StartsWith

true if the character sequence represented by the argument is a prefix of the character sequence represented by this string; false otherwise. Note also that true will be returned if the argument is an empty string or is equal to this String object as determined by the equals(Object) method.

Java String.startsWith

Stockish answered 28/9, 2008 at 9:4 Comment(0)
B
13

Let's just say "abcd".StartsWith("") returns false.

if so then what does the following expression eval to, true or false:

 ("abcd".Substring(0,0) == "")

it turns out that evals to true, so the string does start with the empty string ;-), or put in other words, the substring of "abcd" starting at position 0 and having 0 length equals the empty string "". Pretty logical imo.

Barling answered 16/10, 2008 at 14:58 Comment(4)
The fact that "abcd".Substring(0, 0) returns an empty string does not mean that "abcd" actually starts with an empty string. The result may as well have been declared 'undefined', as null would've been an equally appropriate return value.Zoila
@TomLint No. You usually combine conditions IE x.FirstName.StartsWith(userEnteredFirstName) && x.LastName.StartsWith(userEnteredLastName) .... This makes the condition work even if one of the entered valeus is empty string.Barling
@TomLint But it would be strange to declare the result null or undefined or anything other than '', because why would asking for 1 character from the start give you a string with at most 1 characters but asking for 0 characters from the start would then not give you a string with at most 0 characters but something that isn't a string at all?Mebane
That's precisely the problem. An empty string isn't really a string at all. "abcd".StartsWith("") should return false, and "abcd".Substring(0,0) really should throw an ArgumentOutOfRangeException for its second argument or, even better, an InvalidOperationException, since retrieving a zero-length sub string is most certainly a programming error.Zoila
A
7

In C# this is how the specification tells it to react;

To be equal, value must be an empty string (Empty), a reference to this same instance, or match the beginning of this instance.

Aqua answered 28/9, 2008 at 9:5 Comment(0)
S
5

The first N characters of the two strings are identical. N being the length of the second string, i.e. zero.

Seaton answered 28/9, 2008 at 9:5 Comment(0)
H
5

Why does “abcd”.StartsWith(“”) return true?

THE REAL ANSWER:

It has to be that way otherwise you'd have the case where

    "".startsWith("") == false 
    "".equals("") == true

    but yet

    "a".startsWith("a") == true
    "a".equals("a") == true

and then we'd have Y2K all over again because all the bank software that depends on equal strings starting with themselves will get our accounts mixed up and suddenly Bill Gates will have my wealth and I'd have his, and damn it! Fate just isn't that kind to me.

Hubey answered 21/6, 2011 at 23:10 Comment(3)
I disagree. "".startsWith("") should equal true, because the strings are identical, and not because of some weird business logic.Zoila
@TomLint You're in fact agreeing with the assertation in the answer...Bulbiferous
@Bulbiferous in hindsight, and after replying to a response to a comment of mine under another answer to the OP's question, I retract my previous comment. "".StartsWith("") should, in my opinion, indeed return false. Aside from equality, every operation on an empty string returns a false-y value, by virtue of an empty string not having anything in it to operate onZoila
V
4

Just for the record, String.StartsWith() internally calls the method System.Globalization.CultureInfo.IsPrefix() which makes the following check explicitly:

if (prefix.Length == 0)
{
    return true;
}
Vanderhoek answered 27/1, 2009 at 17:39 Comment(0)
A
1

Because a string begins well with "nothing".

Autocade answered 28/9, 2008 at 9:5 Comment(1)
... that is if string.empty is nothing! This over-simplification cannot be generalized. I suggest we follow the more set theory-oriented discussions.Outward
W
1

If you think of it in regular expressions terms, it makes sense. Every string (not just "abcd", also "" and "sdf\nff") , returns true when evaluating the regular expression of 'starts with empty string'.

Wreckful answered 28/9, 2008 at 9:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.