2012-04-02 25 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