如何在给定数组中的某个元素的情况下找到下一个元素

时间:2014-11-27 15:05:24

标签: ruby arrays

我编写了一个方法来获取数组中给定元素之后的下一个元素。如果我使用c提供方法,我希望它返回e;如果e,我希望它返回a等等:

array = %w[a f c e]

def find_element_after(element, array)
  index = array.find_index(element) + 1
  array.at(index)
end

array.find_element_after("c", array)

如果我传入最后一个元素,我将获得nil。但我想要返回第一个元素。

我可以使用ifelse解决此问题。但我想知道Ruby是否有更好的方法?

4 个答案:

答案 0 :(得分:4)

您可以修改您的方法,将数组大小考虑在内,如下所示:

array = %w[a f c e]

def find_element_after(element, array)
  index = array.find_index(element) + 1
  array.at(index % array.size) # divide calculated index modulo array size
end

find_element_after('e', array)
# => "a"

如果你想让你的方法证明传递不是数组成员的参数,你可以这样做:

def find_element_after(element, array)
  index = array.find_index(element)
  array.at((index + 1) % array.size) if index
end
find_element_after('u', array)
# => nil

或:

def find_element_after(element, array)
  return nil unless array.include?(element)
  index = array.find_index(element)
  array.at(index % array.size)
end

如你所见,有很多可能的解决方案。随意尝试。

答案 1 :(得分:2)

如果传入最后一个元素,它实际上是有效的。索引将被计算到最后一个索引,并从数组中检索lastindex + 1处的元素返回nil

问题是当您提供数组中不存在的元素时。这种情况会导致indexnil,然后在您呼叫NoMethodError时抛出+ 1

要解决此问题,请按以下方式定义您的方法:

def find_element_after(element, array)
  index = array.find_index(element)
  array.at(index + 1) if index
end

这是一个演示现在如何运作的演示(run online):

array = %w[a f c e]

def find_element_after(element, array)
  index = array.find_index(element)
  array.at(index + 1) if index
end

p find_element_after("c", array) # element in the middle - prints "e"
p find_element_after("e", array) # last element - prints "nil"
p find_element_after("z", array) # element not present in the array - prints "nil" (no error)

答案 2 :(得分:1)

您可以使用each_cons使用对迭代数组:

def find_element_after(element, array)
  cons = array.each_cons(2).find { |i1, i2| i1 == element }
  cons.nil? ? array.first : cons.last
end

find_element_after('c', array)
# => "e"
find_element_after('e', array)
# => "a"

答案 3 :(得分:1)

以下是其他一些方法。

#1使用方法Array#rotate

def nxt(arr, e)
  arr.rotate(arr.index(e)+1).first
end

arr = %w[a f c e]

nxt(arr, 'a') #=> "f"
nxt(arr, 'f') #=> "c"
nxt(arr, 'c') #=> "e"
nxt(arr, 'e') #=> "a"

我认为这样做很好,但它的缺点是创建了一个大小为arr的临时数组。

#2使用Array#rotate构建哈希

h = Hash[arr.zip(arr.rotate(1))]
  #=> {"a"=>"f", "f"=>"c", "c"=>"e", "e"=>"a"}

h['a'] #=> "f"
h['f'] #=> "c"
h['c'] #=> "e"
h['e'] #=> "a"

#3使用Array#cycle创建枚举器

enum = arr.cycle

def nxt(enum, v)
  until enum.next == v do
  end
  enum.next
end

nxt(enum, 'a') #=> "f"
nxt(enum, 'f') #=> "c"
nxt(enum, 'c') #=> "e"
nxt(enum, 'e') #=> "a"

如果要绘制多个值,后两种方法应该相对有效。