Why does Ruby return for `str [-1..1]` what does it do?

Suppose we have a string str . If str contains only one character, for example str = "1" , then str[-1..1] returns 1 .
But if size ( length ) str longer than one, for example str = "anything else" , then str[-1..1] returns "" (empty string).

Why does Ruby interpret string slicing in this way?

+5
source share
3 answers

This behavior is how character ranges work.

The beginning of the range is -1, which is the last character in the string. The end of the range is 1, which is the second position from the very beginning.

So, for a single-character string, this is equivalent to 0..1, which is the only character.

For a two-character string, this is 1..1, which is the second character.

For a three-character string, this is 2..1, which is an empty string. And so on for longer lines.

+6
source

To get a non-trivial substring, the start position must represent the position before the end position.

For a string with the same length, index -1 matches index 0 , which is less than 1 . Thus, [-1..1] gives a non-trivial substring.

For a string longer than one character, index -1 greater than index 0 . Thus, [-1..1] cannot give a non-trivial substring and, by default, returns an empty string.

+3
source

As a rule, indexes help me:

 # 0 1 2 3 4 5 6 7 8 9 10 11 12 str = 'a' 'n' 'y' 't' 'h' 'i' 'n' 'g' ' ' 'e' 'l' 's' 'e' #=> "anything else" # -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 

You can refer to each character by its positive or negative index. For example, you can use 3 or -10 to mean "t" :

 str[3] #=> "t" str[-10] #=> "t" 

and 7 or -6 to refer to "g" :

 str[7] #=> "g" str[-6] #=> "g" 

Similarly, you can use each of these indices to retrieve the "thing" across a range:

 str[3..7] #=> "thing" str[3..-6] #=> "thing" str[-10..7] #=> "thing" str[-10..-6] #=> "thing" 

str[-1..1] , however, will return an empty string, because -1 refers to the last character, and 1 refers to the second. This would be equivalent to str[12..1] .

But if the string consists of one character, this range becomes valid:

 # 0 str = '1' # -1 str[-1..1] #=> "1" 

In fact, 1 refers to the index after the first character, so 0 will be enough:

 str[-1..0] #=> "1" 
+1
source

Source: https://habr.com/ru/post/1260418/


All Articles