How to get the last 5 elements of an array?

G

Gavin Sinclair

Hi,

I want to extract the last 5 elements of an array 'x'. I know that x
is an array, but I don't know how many elements it has. What do you
suggest?

In code, this is what I want.

def last5(arr)
# Fill me in.
end

last5 [] # -> []
last5 [1] # -> [1]
last5 [1,2] # -> [1,2]
last5 [1,2,3,4,5,6,7] # -> [3,4,5,6,7]
last5 nil # -> error

Thanks,
Gavin
 
M

Martin Stannard

Hi,

I want to extract the last 5 elements of an array 'x'. I know that x
is an array, but I don't know how many elements it has. What do you
suggest?

In code, this is what I want.

def last5(arr)
# Fill me in.
end

last5 [] # -> []
last5 [1] # -> [1]
last5 [1,2] # -> [1,2]
last5 [1,2,3,4,5,6,7] # -> [3,4,5,6,7]
last5 nil # -> error

Thanks,
Gavin

Hi Gavin,

ruby -e 'p [1, 2, 3, 4, 5, 6, 7, 8, 9, 10][-5..-1]'

Martin
 
H

Harry Ohlsen

Gavin said:
Hi,

I want to extract the last 5 elements of an array 'x'. I know that x
is an array, but I don't know how many elements it has. What do you
suggest?

In code, this is what I want.

def last5(arr)
# Fill me in.
end

last5 [] # -> []
last5 [1] # -> [1]
last5 [1,2] # -> [1,2]
last5 [1,2,3,4,5,6,7] # -> [3,4,5,6,7]
last5 nil # -> error
How about ...

def last5(arr)
if arr.length < 5
arr.dup
else
arr[-5, 5]
end
end
 
X

Xavier

Hi,

I want to extract the last 5 elements of an array 'x'. I know that x
is an array, but I don't know how many elements it has. What do you
suggest?

In code, this is what I want.

def last5(arr)
# Fill me in.
end

last5 [] # -> []
last5 [1] # -> [1]
last5 [1,2] # -> [1,2]
last5 [1,2,3,4,5,6,7] # -> [3,4,5,6,7]
last5 nil # -> error

Thanks,
Gavin

Hi Gavin,

ruby -e 'p [1, 2, 3, 4, 5, 6, 7, 8, 9, 10][-5..-1]'

Martin

But [1,2][-5,5] => nil
and Gavin wants [1,2] instead of nil

How about

def last5(arr)
if arr.length<5 then arr else arr[-5,5] end
end
last5 []
=> []
last5 [1]
=> [1]
last5 [1,2]
=> [1, 2]
last5 [1,2,3,4,5,6,7]
=> [3, 4, 5, 6, 7]
last5 nil
NoMethodError: undefined method `length' for nil:NilClass
from (irb):12:in `last5'
from (irb):18
 
G

Gavin Sinclair

But [1,2][-5,5] =>> nil
and Gavin wants [1,2] instead of nil
How about
def last5(arr)
if arr.length<5 then arr else arr[-5,5] end
end


Right. Now should that be necessary? Grabbing the last 5 elements of
an array is the kind of thing that should be easy and obvious in Ruby.

So I propose that Array be changed so that

def last5(arr)
arr[-5..-1]
end

meets the requirements I gave earlier. That is

last5 [] # -> []
last5 [1] # -> [1]
last5 [1,2] # -> [1,2]
last5 [1,2,3,4,5,6,7] # -> [3,4,5,6,7]
last5 nil # -> error

Any thoughts before I raise an RCR?

Cheers,
Gavin
 
M

Martin Stannard

But [1,2][-5,5] => nil
and Gavin wants [1,2] instead of nil

How about

def last5(arr)
if arr.length<5 then arr else arr[-5,5] end
end
last5 []
=> []
last5 [1]
=> [1]
last5 [1,2]
=> [1, 2]
last5 [1,2,3,4,5,6,7]
=> [3, 4, 5, 6, 7]
last5 nil
NoMethodError: undefined method `length' for nil:NilClass
from (irb):12:in `last5'
from (irb):18

Doh! That'll teach me to not read the post carefully.

cheers,

Martin
 
D

David Alan Black

Hi --

Gavin Sinclair said:
But [1,2][-5,5] =>> nil
and Gavin wants [1,2] instead of nil
How about
def last5(arr)
if arr.length<5 then arr else arr[-5,5] end
end


Right. Now should that be necessary? Grabbing the last 5 elements of
an array is the kind of thing that should be easy and obvious in Ruby.

So I propose that Array be changed so that

def last5(arr)
arr[-5..-1]
end

meets the requirements I gave earlier. That is

last5 [] # -> []
last5 [1] # -> [1]
last5 [1,2] # -> [1,2]
last5 [1,2,3,4,5,6,7] # -> [3,4,5,6,7]
last5 nil # -> error

Any thoughts before I raise an RCR?

Yes. I don't think it makes sense for this:

arr[-5..-1].include?(arr[-3])

to be false, since this:

(-5..-1).include?(-3)

is true.

But none of this matters, because Array#last takes an argument :)

irb(main):008:0> [1,2,3].last(2)
=> [2, 3]


David
 
D

David Alan Black

David Alan Black said:
But none of this matters, because Array#last takes an argument :)

irb(main):008:0> [1,2,3].last(2)
=> [2, 3]

Whoops, I forgot the example that corresponds to what you want to
do:

irb(main):003:0> [1,2,3].last(5)
=> [1, 2, 3]


David
 
G

Gavin Sinclair

Any thoughts before I raise an RCR?

Yes. I don't think it makes sense for this:

arr[-5..-1].include?(arr[-3])

to be false, since this:

(-5..-1).include?(-3)

is true.

Your first condition would be justifiably false if arr == [1,2], even
if I submitted an RCR and it were accepted and implemented.
But none of this matters, because Array#last takes an argument :)
irb(main):008:0> [1,2,3].last(2)
=> [2, 3]

Sweet! Learn something new every day. That quells the desire for an
RCR, because I'm not sure of the theoretical ground for such, your
example notwithstanding.

For example, consider this:

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
x[-5..3] # -> nil

If even *that* returns nil, when *all* numbers in the range are valid
indexes, then...

Also, there's everybody's favourite example:

x[10..15] # -> []
x[11..15] # -> nil

I'd rather see 'arr[range]' *always* return an array, no matter the
value of 'arr' and 'range'.

Thanks,
Gavin
 
D

David Alan Black

Hi --

Gavin Sinclair said:
For example, consider this:

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
x[-5..3] # -> nil

If even *that* returns nil, when *all* numbers in the range are valid
indexes, then...

Also, there's everybody's favourite example:

x[10..15] # -> []
x[11..15] # -> nil

I'd rather see 'arr[range]' *always* return an array, no matter the
value of 'arr' and 'range'.

I guess it comes down to the necessity to translate between the very
different perspectives of Arrays and Ranges when it comes to counting.
For example, for a 5-element array, -3 > 1, counting Array-style. I
don't know whether there's a way to un-anomalize it; it may be one of
these lumps that can be moved around under the carpet but is still
always somewhere.


David
 
R

Robert Klemme

Harry Ohlsen said:
Gavin said:
Hi,

I want to extract the last 5 elements of an array 'x'. I know that x
is an array, but I don't know how many elements it has. What do you
suggest?

In code, this is what I want.

def last5(arr)
# Fill me in.
end

last5 [] # -> []
last5 [1] # -> [1]
last5 [1,2] # -> [1,2]
last5 [1,2,3,4,5,6,7] # -> [3,4,5,6,7]
last5 nil # -> error
How about ...

def last5(arr)
if arr.length < 5
arr.dup
else
arr[-5, 5]
end
end

Not general enough. Rather

irb(main):001:0> class Array;def last(n);size>=n ? self[-n .. -1] :
self;end;end
=> nil
irb(main):002:0> [1,2].last 5
=> [1, 2]
irb(main):003:0> [1,2,3,4,5,6,7].last 5
=> [3, 4, 5, 6, 7]

robert
 
D

David Alan Black

Hi --

Robert Klemme said:
Harry Ohlsen said:
How about ...

def last5(arr)
if arr.length < 5
arr.dup
else
arr[-5, 5]
end
end

Not general enough. Rather

irb(main):001:0> class Array;def last(n);size>=n ? self[-n .. -1] :
self;end;end
=> nil
irb(main):002:0> [1,2].last 5
=> [1, 2]
irb(main):003:0> [1,2,3,4,5,6,7].last 5
=> [3, 4, 5, 6, 7]

Isn't that how Array#last works now?


David
 
T

ts

D> "Robert Klemme said:
irb(main):001:0> class Array;def last(n);size>=n ? self[-n .. -1] :
self;end;end

D> Isn't that how Array#last works now?

No, for 2 reasons
* Array#last always return an object Array
* it dup the return value when size < n

svg% cat b.rb
#!/usr/bin/ruby
class Array
def lest(n)
size>=n ?self[-n..-1]:self
end

end

class A < Array
end

a = A.new(2, 1)
p a.lest(1).class
p a.last(1).class
svg%

svg% b.rb
A
Array
svg%


Guy Decoux
 
R

Robert Klemme

David Alan Black said:
Hi --

Robert Klemme said:
Harry Ohlsen said:
How about ...

def last5(arr)
if arr.length < 5
arr.dup
else
arr[-5, 5]
end
end

Not general enough. Rather

irb(main):001:0> class Array;def last(n);size>=n ? self[-n .. -1] :
self;end;end
=> nil
irb(main):002:0> [1,2].last 5
=> [1, 2]
irb(main):003:0> [1,2,3,4,5,6,7].last 5
=> [3, 4, 5, 6, 7]

Isn't that how Array#last works now?

Oh, I didn't even notice there is Array#last. :)

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top