Skip to content

Instantly share code, notes, and snippets.

@Groxx
Last active August 29, 2015 14:25
Show Gist options
  • Save Groxx/cdcc587acae22baed917 to your computer and use it in GitHub Desktop.
Save Groxx/cdcc587acae22baed917 to your computer and use it in GitHub Desktop.

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);

if you had used indexes

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?

Random interjection

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment