2012-09-24 80 views
1

我有一個數組的陣列,如下所示:[[1, "dog"], [2, "cat"], [2, "bird"], [3, "monkey"]]。我想檢查更大的數組是否包含給定數字的數組,而不考慮數組的動物元素。我也不想循環通過陣列,因爲這將變得計算量很大。Rails通過數組陣列搜索

因此,像@boolean = bigArray.include?([2, *]),除了一些實際工作......

+1

無論是這樣或那樣的顯式或隱式,你都在循環。沒有什麼神奇的方法可以通過一個數組來檢查每個元素,而不需要循環。如果你關心性能,你選擇了錯誤的數據容器。 – meagar

+0

另外,你給了我們一個測試用例,其中密鑰是重複的,但沒有告訴我們你期望發生什麼。如果你的'bigArray.include ...'返回'[2,'cat']',或者它應該返回'[「cat」,「bird」]'或者什麼? – meagar

回答

3

你有兩種可能的解決方案。檢測元件陣列中或數組轉換成Hash

使用Enumerable#detect,將盡快找到一個匹配,否則停止並返回,nil

> a = [[1, "dog"], [2, "cat"], [2, "bird"], [3, "monkey"]] 
=> [[1, "dog"], [2, "cat"], [2, "bird"], [3, "monkey"]] 
> a.detect{ |(n, _)| n == 2 } 
=> [2, "cat"] 
> a.detect{ |(n, _)| n == 10 } 
=> nil 

如果你想要將它添加到Array類像你的榜樣,並迫使它返回一個布爾值,這樣做:

class Array 
    def custom_include?(num) 
    !!detect{ |(n, _)| num == n } 
    end 
end 

例子:

> a.custom_include?(2) 
=> true 
> a.custom_include?(10) 
=> false 

如果你不關心碰撞鍵,你可以將數組轉換成Hash並查看鍵是否存在。

> a = [[1, "dog"], [2, "cat"], [2, "bird"], [3, "monkey"]] 
=> [[1, "dog"], [2, "cat"], [2, "bird"], [3, "monkey"]] 
> Hash[a][2] 
=> "bird" 
> Hash[a][10] 
=> nil 
0

不涉及循環的一個非常簡單的方法是將結構轉換爲散列。你的陣列恰巧在這個理想的格式:

values = [[1, "dog"], [2, "cat"], [2, "bird"], [3, "monkey"]] 

Hash[values][2] # "bird" 

你將失去​​的第一個值對每個關鍵,但它足以說明一個鍵是否存在。