2012-04-02 56 views
0

這個職位上是非常相似,我以前的一個,但數據結構在這裏是不同的: Joining an array of keys to a hash with key value pairs like excel vlookup仰望的按鍵陣列散列的紅寶石陣列,如Excel VLOOKUP

我從我的Mysql2數據::結果回來這樣的陣列哈希:

data = [{"isbn" => "1234", "title"=>"apple"},{"isbn" => "5678", "title"=>"banana"},{"isbn" => "2121", "title"=>"car"}] 

而且我原來的那個我想比較的ISBN的列表是該數組:

isbns = ["1234","2121", "5454", "5678"] 

我正在尋找它使用的ISBN數組,並返回這樣的結果的函數:

result = [{"isbn"=>"1234","title"=>"apple"}, {"isbn"=> "2121", "title"=>"car"}, nil, {"isbn"=>"5678","title"=>"banana"}] 

的「駕駛」陣列的ISBN ...想象從ISBN號做一個VLOOKUP數據...任何物品不在數據中,但在isbns中應返回nil。應該返回isbns的原始順序,並且返回數據應該是散列數組。

回答

1
isbns.map { |isbn| data.find { |h| h["isbn"] == isbn} } 
#=> [{"isbn"=>"1234", "title"=>"apple"}, {"isbn"=>"2121", "title"=>"car"}, nil, {"isbn"=>"5678", "title"=>"banana"}] 
+0

duuuude的因素...謝謝! – hagope 2012-04-02 21:16:33

1

@Michael Kohl的答案簡潔而正確。但是,如果這些數據集很大,則O(n * m/2)效率不高。另一種方法是將數據向量轉換爲O(m)中的散列,然後在O(n)中爲O(n + m)的運行時執行映射。

data_lookup = data.inject({}) {|m,v| m[v["isbn"]] = v; m} # O(data.size) 
result = isbns.map { |isbn| data_lookup[isbn] }   # O(isbns.size) 

如果您的數據和ISBN集合了大小1000的每一個,這將是快了250

+0

哦該死的這是大學畢業sci回來咬我在屁股...欣賞這個建議,我一定會試一試 – hagope 2012-04-03 01:09:27

+0

在1000條記錄上,你的通話費用爲0.008449514,第一次通話費用爲0.234835044 s – hagope 2012-04-03 01:39:34

+0

@hagope這與我基於大O分析的估計非常接近。如果您只偶爾運行此計算,則不是一個大問題(儘管235ms對於單個Web請求而言是實質性延遲)。如果您的規模很大,並且需要以500次/秒的速度進行計算,那麼快速版本可以使用一個普通的四核處理器來管理,而較慢的版本可能需要10臺12核服務器才能維持。 – dbenhur 2012-04-03 03:08:05