2017-08-04 74 views
0

乘以電流值I具有該散列:哈希迭代,同時通過連續的值

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

我將一個號碼傳遞給我的方法,來檢查,如果在散列任何兩個連續值相乘,將匹配數。

例如: Number是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]可能是空的,我使用錯誤的語法。 我想完成什麼,但我已經嘗試了'select'和'keep_if',是讓哈希函數返回兩個鍵/值對。在這種情況下的示例 - [[4, 23][5, 34]

我嘗試過的另一件事是更有希望的是使用if語句,然後將兩個值捕獲到另一個數組。它的工作,但有點過分。有什麼建議麼?

+1

請記住,哈希僅保留插入順序,否則它們根本沒有內在順序。改變哈希可以隨機地對訂單進行加擾。通常最好將序列存儲在排序對數組非常重要的地方。 – tadman

+0

@tadman這就是爲什麼我使用'each_with_index',因爲我的理解是會保留哈希的順序。 – stuartambient

+0

我在說的是,當你假設哈希按特定的順序時,如果沒有,你會感到驚訝。陣列不會以這種方式混淆自己。 – tadman

回答

3

嘗試這一個

myhash.values.each_cons(2).find { |pair| pair.first * pair.last == 748 } 
  • 值=>提取物從散列只是的值(因此,我們有一個數組,沒有更多的鍵)
  • each_cons(2)=>我想要一個新的陣列對每兩個相鄰項
  • 查找=>發現表達式匹配的陣列中的一對,並返回或獲得nil否則
+0

很好用!對於我來說,有些東西需要學習,因爲我不知道它到底在說什麼,但我會弄明白。謝謝! – stuartambient

+1

我更新了我的答案,並試圖解釋 – Ursus

+0

非常酷!感謝您的解答和解釋。 – stuartambient

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#peek,當它試圖Enumerator#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 
+2

整齊地做,超級duper。請注意,乘法的順序很重要,所以'enum.peek * enum.next'就不足夠了。 –

+0

我得到了散列轉換爲枚舉。儘管如此,問題是要抓住匹配目標的實際相乘值。這就是我在嘗試'h [v]和h [v + 1]'時遇到的情況。 – stuartambient

+0

只是爲了進一步闡述我只想要匹配時返回的數字。在我之前的實驗中,我發現它返回了一個數字數組它沒有那麼好,但繼續吐出相同的數組,直到迭代結束。我一直想用'when'來表示只是返回乘以匹配目標時的那些值。當然,「何時」在這種情況下不起作用。 – stuartambient