say you have a string: "hello". this is the sequence of characters:
[h, e, l, l, o]
spread it out a bit so the string looks like this, with "|" as the divider and the end-markers.
| h | e | l | l | o |
0 1 2 3 4 <- these are the indexes of the characters
0 1 2 3 4 5 <- these are the things between the indexes, aka "fence posts"
you use indexes when getting one element, and fence posts when getting a sub-section of a thing. (all this also applies to sub-arrays ("splices", sometimes other names), and sub-anything-with-an-index)
when you get a sub-section, you grab everything between fence posts.
e.g. "hello".substring(0, 2)
:
| h | e | l | l | o |
0 1 2 3 4 5
┗━━━━━━━┛
you get "he"
.
say you do "hello".substring(3,3)
:
| h | e | l | l | o |
0 1 2 3 4 5
┗━┛
you get ""
. null
would also make sense, because you're getting "nothing".
but most languages will return the same type, so you get ""
for strings, []
for arrays, etc.
You can get the whole thing, with "hello".substring(0, 5)
:
| h | e | l | l | o |
0 1 2 3 4 5
┗━━━━━━━━━━━━━━━━━━━┛
Say you don't know how long the string is up-front, and you want to remove the last letter:
you would do ".....wxyz".substring(0, length-1)
:
| ......... | x | y | z |
0 1 2 ... len-3 len-2 len-1 len
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
and you get "....wxy"
.
all of which might still seem odd. but it lets you do things like this:
remove X
letters from the beginning and Y
letters from the end:
s = "asdfasfdasfasdf....";
s.substring(X, s.length - Y);
say you wanted to just get the third letter:
"hello".substring(2,2):
| h | e | l | l | o |
0 1 2 3 4
┗━┛
and you get "l"
. easy enough.
now say you wanted to remove the first three and the last two, leaving you with nothing:
"hello".substring(3,2)
| h | e | l | l | o |
0 1 2 3 4
┛━━━┗
??? what would that even mean? maybe "ll"
because it goes between both?
We can certainly declare it's ""
because that could work, just like above.
But is this valid too then? it's the same kind of shape:
"hello".substring(3, 1)
| h | e | l | l | o |
0 1 2 3 4
┛━━━━━━━┗
does that get ""
too, or null
, or "ell"
, or "lle"
because it's backwards, or cause an explosion?
with fence posts, usually
"asdf".substring(X, X-1)
is an error, because it would look like this:"hello".substring(3, 2)
| h | e | l | l | o | 0 1 2 3 4 5 ┛━━━┗
which looks entirely different than `(3,3)`'s `┗━┛` shape.
Also, to remove X
from the front and Y
from the back, it would have to be:
s.substring(X, s.length - Y - 1)
so things like "remove last letter" would be:
s.substring(X, s.length - 2)
long story short, if it used indexes, you would have to:
- add an extra 1 to include a letter (but only at the end)
- remove an extra 1 from the length to exclude a letter (but only at the end)
- allow
(X, X-1)
, but not(X, X-2)
(or make(X, X-123456789)
always work)
with fence posts, you just use the number you want directly.