首页 > 解决方案 > 您如何从任何给定数组的当前索引中获取前 2 个和后 2 个元素?

问题描述

给定一个数组

arr = ["a", "b", "c", "d"]

我想要一个采用索引和数组的方法

def previous_and_next_elems(idx, arr)
  ...
end

比如说idx = 1

$> previous_and_next_elems(1, arr)
$> [['a'], ['c', 'd']]

请注意,由于之前只存在单个项目,idx=1因此只有元素a存在。如果没有,则将返回空数组。

标签: ruby

解决方案


arr = ["a", "b", "c", "d", "e"]

def for_and_aft(arr, idx)
  index_range = 0..arr.size-1
  [arr.values_at(*[idx-2, idx-1].grep(index_range)),
   arr.values_at(*[idx+1].grep(index_range))]
end

for_and_aft(arr,0)
  #=> [[], ["b"]] 
for_and_aft(arr,1)
  #=> [["a"], ["c"]] 
for_and_aft(arr,2)
  #=> [["a", "b"], ["d"]] 
for_and_aft(arr,3)
  #=> [["b", "c"], ["e"]] 
for_and_aft(arr,4)
  #=> [["c", "d"], []] 

请参阅Array#values_atEnumerable#grep

考虑idx = 1。执行以下计算。

index_range = 0..arr.size-1
  #=> 0..4

a = [idx-2, idx-1]
  #=> [-1, 0] 
b = a.grep(index_range)
  #=> [0] 
c = arr.values_at(*b)
  #=> ["a"]

d = [idx+1]
  #=> [2] 
e = d.grep(index_range)
  #=> [2] 
f = arr.values_at(*e)
  #=> ["c"] 

[c,f]
  #=> [["a"], ["c"]]

在计算b中,grep使用Range#===来评估

(0..4) === -1
  #=> false 
(0..4) ===  0
  #=> true

因此返回[0]


推荐阅读