Let initial_array = (1..10).to_a
.
I need it to be dynamic on number selection, but for an example: I need to select the number 5
, as well as two elements on either side. Ideally, this would return: [3,4,5,6,7]
.
I know I can use each_cons to return the desired array length, with surrounding numbers. However, to select the desired element, I'm currently using initial_array.each_cons(5).find {|ary| ary.include?(5)}
.
This returns [1,2,3,4,5]
, rather than the desired [3,4,5,6,7]
.
Additionally, I would like the function to work on both ends of the spectrum, with the returned array always at length 5
, unless initial_array.length < 5
, at which point returned_array.length == intial_array.length
.
Thus, initial_array.solution_method(1)
returns [1,2,3,4,5]
,
initial_array.solution_method(10)
returns [6,7,8,9,10]
,
[1,2,3,].solution_method(2)
returns [1,2,3]
.
答案 0 :(得分:2)
It's not a one liner but maybe easier to understand?
input = (1..10)
def select_range(array, num, range)
index = array.index(num) # find the value
return [] if !index # return if the array doesn't include it
array[(index - range)..(index + range)] # return the range of elements
end
p select_range(input.to_a, 5, 2)
output:
[3, 4, 5, 6, 7]
答案 1 :(得分:2)
def grab_part(arr, nbr, option=:avg)
return nil unless (1..arr.size).include?(nbr)
return nil if option!=:avg && !(nbr-1...arr.size).include?(option)
first = (option==:avg) ? (arr.size-nbr)/2 : option-nbr+1
arr[first,nbr]
end
nbr
is the size of the array to be returned. option==:avg
if the "middle" of arr
is to be returned; else option
is an index into arr
identifying the last element of the array to be returned.
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
grab_part(arr,5) #=> [3, 4, 5, 6, 7]
grab_part(arr,5,9) #=> [6, 7, 8, 9, 10]
grab_part(arr,5,4) #=> [1, 2, 3, 4, 5]
The following shows returned values for other values of the second parameter of grab_part
.
(1..arr.size).map do |n|
next if n==5
puts "grab_part(arr,#{n}) \#=> #{ grab_part(arr,n) }"
puts "grab_part(arr,#{n},#{arr.size-1}) \#=> #{grab_part(arr,n,arr.size-1)}"
puts "grab_part(arr,#{n},#{n-1}) \#=> #{grab_part(arr,n,n-1)}\n"
end
grab_part(arr,1) #=> [5]
grab_part(arr,1,9) #=> [10]
grab_part(arr,1,0) #=> [1]
grab_part(arr,2) #=> [5, 6]
grab_part(arr,2,9) #=> [9, 10]
grab_part(arr,2,1) #=> [1, 2]
grab_part(arr,3) #=> [4, 5, 6]
grab_part(arr,3,9) #=> [8, 9, 10]
grab_part(arr,3,2) #=> [1, 2, 3]
grab_part(arr,4) #=> [4, 5, 6, 7]
grab_part(arr,4,9) #=> [7, 8, 9, 10]
grab_part(arr,4,3) #=> [1, 2, 3, 4]
grab_part(arr,6) #=> [3, 4, 5, 6, 7, 8]
grab_part(arr,6,9) #=> [5, 6, 7, 8, 9, 10]
grab_part(arr,6,5) #=> [1, 2, 3, 4, 5, 6]
grab_part(arr,7) #=> [2, 3, 4, 5, 6, 7, 8]
grab_part(arr,7,9) #=> [4, 5, 6, 7, 8, 9, 10]
grab_part(arr,7,6) #=> [1, 2, 3, 4, 5, 6, 7]
grab_part(arr,8) #=> [2, 3, 4, 5, 6, 7, 8, 9]
grab_part(arr,8,9) #=> [3, 4, 5, 6, 7, 8, 9, 10]
grab_part(arr,8,7) #=> [1, 2, 3, 4, 5, 6, 7, 8]
grab_part(arr,9) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
grab_part(arr,9,9) #=> [2, 3, 4, 5, 6, 7, 8, 9, 10]
grab_part(arr,9,8) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
grab_part(arr,10) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
grab_part(arr,10,9) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
A few more.
grab_part(arr,5,6) #=> [5, 6, 7, 8, 9]
#=> [3, 4, 5, 6, 7]
grab_part(arr,5,8) #=> [3, 4, 5, 6, 7]
#=> [5, 6, 7, 8, 9]
grab_part(arr,5,3) #=> [5, 6, 7, 8, 9]
#=> nil
grab_part(arr,5,10) #=> [3, 4, 5, 6, 7]
#=> nil
答案 2 :(得分:1)
To accomplish your task, you can use the slice
method. Just fyi, (1..10)
is a range object, not an array. To use the slice
method, you need to change the range to an array first using (1..10).to_a
slice
takes two inputs, starting index, and length. So you can do (1..10).to_a.slice(2,5)
to get [3,4,5,6,7]
答案 3 :(得分:0)
这是我目前的工作解决方案。它并不像我想的那样雄辩,但它对我所寻找的东西有效。
def grab_neighbors(array, num, range)
index = array.index(num)
target_length = range * 2 + 1
if index < range
return array.slice(0, target_length)
elsif index >= (array.length - range)
return array.slice(-target_length, target_length)
else
return array[(index - range)..(index + range)]
end
end