散列迭代,同时将当前值乘以连续值

时间:2017-08-04 19:08:20

标签: ruby

我有这个哈希:

myhash = { 1=> 2,  2=> 18, 3=> 8,
           4=> 22, 5=> 34, 6=> 16 }

我会将一个数字传递给我的方法,该方法检查哈希中的任何两个连续值是否与该数字相匹配。

实施例: 数字是748,所以迭代应该是2 * 18,18 * 8,8 * 22,22 * 34,34 * 16.正确的答案是哈希值22和34。

我试图让其发挥作用的方法之一

l = myhash.length - 1
product = 748
myhash.take(l).keep_if.each_with_index { |k,v| myhash[v] * myhash[v+1] == product }

令人惊讶的是,这是undefined method *'为零:NilClass`。我惊讶地说,因为我在另一个地方成功地使用了那种倍增。

我接受它,因为[v + 1]可能是空的,我使用了错误的语法。 虽然我想完成什么,但我已经尝试过选择'和' keep_if',是让哈希返回两个键/值对。本例中的示例 - [[4, 23][5, 34]

我尝试的另一件事更有希望的是使用if语句然后将两个值捕获到另一个数组。它工作但有点不稳定。有什么建议吗?

2 个答案:

答案 0 :(得分:3)

试试这个

myhash.values.each_cons(2).find { |pair| pair.first * pair.last == 748 }
  • values =>只提取哈希值(所以我们有一个数组,没有更多键)
  • each_cons(2)=>我想要一个包含每两个相邻项目对的新数组
  • find =>在数组中找到与表达式匹配的对并返回该对,否则获取nil

答案 1 :(得分:3)

您可以使用枚举器。

def doit(arr, target)
  enum = arr.to_enum
  loop { return true if enum.next * enum.peek == target }
  false
end

doit [1,2,3,4,5], 12
  #=> true
doit [1,2,3,4,5], 13
  #=> false

Enumerator#peekEnumerator#next生成最后一个值后尝试生成值时会引发StopIteration异常。 Kernel#loop通过突破循环来处理异常。

要返回产品等于指定值的前两个连续数字,否则为nil,请按以下步骤修改上述内容。

def doit(arr, target)
  enum = arr.to_enum
  loop do
    n = enum.next
    p = enum.peek
    return [n, p] if n*p == target
  end
  nil
end

doit [1,2,3,4,5], 12
  #=> [3, 4]
doit [1,2,3,4,5], 13
  #=> nil