Reputation: 71
I have an array like this: [7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
What's the simplest way to return each item in the array from position 6 until 0 where the resulting array looks like: [1,2,3,4,5,6,7]
This positions in the array can be dynamic, for example passing in 4 and 9 should return [11,12,1,2,3,4]
I'm wondering if there's a method that accomplishes this in Rails api.
Thanks in advance
EDIT
Let's assume that no negative numbers, so doing array[2..-2]
wont work.
Array#splice
almost works for this, but if the second position is less than the first, it returns nil
.
Upvotes: 6
Views: 1759
Reputation: 4012
def foo a, s, e
a = e < s ? (a[s,a.size] << a[0..e]).flatten : a[s..e]
end
a = [7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
a = foo(a, 6, 0) # => [1, 2, 3, 4, 5, 6, 7]
a = foo(a, 4, 9) # => [11, 12, 1, 2, 3, 4]
Upvotes: 0
Reputation: 110675
A couple more ways (my preference being for #1).
a = [7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
#1
def foo a, min, max
as = a.size
max += as if max < min
(min..max).map { |i| a[i%as] }
end
foo(a, 6, 0) # => [ 1, 2, 3, 4, 5, 6, 7]
foo(a, 4, 9) # => [11, 12, 1, 2, 3, 4]
#2
def foo a, min, max
max += a.size if max < min
e = a.cycle
min.times { e.next }
(max-min+1).times.map { e.next }
end
foo(a, 6, 0) # => [ 1, 2, 3, 4, 5, 6, 7]
foo(a, 4, 9) # => [11, 12, 1, 2, 3, 4]
Upvotes: 0
Reputation: 2142
class Array
def get_sub_array(start,last)
(start > last) ? (self[start..-1] + self[0..last]) : self[start..last]
end
end
Then
a = [7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
a.get_sub_array(6,0)
#[1, 2, 3, 4, 5, 6, 7]
Or if you don't want to monkey patch
You could have a method like
def get_sub_array(array, start,last)
(start > last) ? (array[start..-1] + array[0..last]) : array[start..last]
end
a = [7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
get_sub_array(a,6,0)
#[1, 2, 3, 4, 5, 6, 7]
Upvotes: 2
Reputation: 9173
def some_function(some_array,start_val=6, end_val=0)
if end_val > start_val
some_array[start_val,(end_val - start_val)]
else
(some_array[start_val, some_array.size] << some_array[0, (end_val)]).flatten
end
end
You can use ternary operator to make it one liner too:
def some_function(some_array,start_val=6, end_val=0)
end_val > start_val ? some_array[start_val,(end_val - start_val)] : (some_array[start_val, some_array.size] << some_array[0, (end_val)]).flatten
end
a = [7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
some_function(a) # => [1, 2, 3, 4, 5, 6, 7]
some_function(a, 4, 9) # => [11, 12, 1, 2, 3, 4]
Upvotes: 1
Reputation: 168081
def foo a, min, max
a.rotate(min).first((max - min) % a.length + 1)
end
a = [7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
foo(a, 6, 0) # => [1, 2, 3, 4, 5, 6, 7]
foo(a, 4, 9) # => [11, 12, 1, 2, 3, 4]
Upvotes: 4
Reputation: 941
min=6
max=0
arr = [7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
result = []
if max<min
result << arr[min..arr.length]
result << arr[0..max]
else
result << arr[min..max]
end
Upvotes: 0
Reputation: 470
myArray = [7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
myArray[6..-1] returns [1, 2, 3, 4, 5, 6]
myArray[4..9] returns [11,12,1,2,3,4]
Upvotes: -1