Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does array.slice behave differently for (length, n)

Tags:

arrays

ruby

If I have an array a:

  1. a[a.length] returns nil. Good.
  2. a[a.length, x] returns []. Good.
  3. a[a.length+x, y] returns nil. Inconsistent with 2.

While this behavior is documented, it seems odd.

Can anybody explain the reasons behind this design?

like image 782
Diego Mijelshon Avatar asked Jul 10 '10 12:07

Diego Mijelshon


People also ask

What is the purpose of array slicing?

The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end ( end not included) where start and end represent the index of items in that array.

Is slice operation allowed in array?

Depending on the programming language, an array slice can be made out of non-consecutive elements. Also depending on the language, the elements of the new array may be aliased to (i.e., share memory with) those of the original array.

Can we slice array in C?

Array-slicing is supported in the print and display commands for C, C++, and Fortran. Expression that should evaluate to an array or pointer type. First element to be printed. Defaults to 0.

Does slice accept negative index?

slice() is more flexible than substring() because it allows negative argument values.


3 Answers

Consider this

a = [0, 1, 2, 3] #=> [0, 1, 2, 3]
a[0, 10]         #=> [0, 1, 2, 3]
a[1, 10]         #=>    [1, 2, 3]
a[2, 10]         #=>       [2, 3]
a[3, 10]         #=>          [3]
a[4, 10]         #=>           []
a[5, 10]         #=>          nil

So a[4, 10] is the slice between the 3 and the end of the array which is []

Where as a[4] and a[5, 10] are accessing elements that aren't in the array

It may help to think of the slice points as being between the elements, rather than the elements themselves.

[ <0> 0 <1> 1 <2> 2 <3> 3 <4> ]

Where <n> are the points between elements and the start/end of the array. a[4, 10] then becomes a selection of 10 elements, starting from point 4. Whereas a[5, 10] starts from point 5, which is not part of the list.

like image 77
John La Rooy Avatar answered Oct 05 '22 04:10

John La Rooy


Look to your friendly Lispy languages for the answer. The philosophy you're looking for began with languages whose specialty was LISt Processing (thus, LISP). For instance, here's one way of creating lists in Haskell:

1:[] => [1] 
1:2:3:[] => [1,2,3] 

This is called cons-ing, for 'constructing' a list. If the idea hasn't clicked yet, consider this: an array is created by adding elements to an empty list, not to 'nil'.

like image 35
Mugabo Avatar answered Oct 05 '22 04:10

Mugabo


To begin with, this case is a special case in Ruby.

This special case also has an explanation to it:

There is a point of difference when you speak about indexing an array, and slicing it.

Indexing an array means to have an unique Position which helps you access the value at a given Index.

Slicing on the other hand means to "cut" between two points (P.S points here are index)

Consider this:

array = [Ruby, PHP, JS, HTML, CSS]

Indexing in this case will be:

array = [Ruby, PHP, JS, HTML, CSS]
Index =   0.    1.  2.  3.    4. 

Slicing in the same case will be:

array = [Ruby, PHP, JS, HTML, CSS]
Slice = 0.   1.   2.  3.    4.   5.

Hence:

array[5,n] #[] i.e. you get an empty array.
array[6,n] #nil i.e. NIL

Reference

like image 25
Abhishek Jain Avatar answered Oct 05 '22 04:10

Abhishek Jain