[英]How do I efficiently extract all values with a certain key name from a hash of hashes?
我有這些數據:
members = {"total"=>3, "data"=>[
{"email"=>"foo@example.org", "timestamp"=>"2013-03-16 01:11:01"},
{"email"=>"bar@example.org", "timestamp"=>"2013-03-16 02:07:30"},
{"email"=>"exx@example.org", "timestamp"=>"2013-03-16 03:06:24"}
]}
並希望生成如下數組:
["foo@example.org", "bar@example.org", "exx@example.org"]
目前我正在使用:
members['data'].collect { |h| h['email'] }
我有Rails可用。
除了其他答案之外,我將添加如果您能夠使用symbols
作為keys
來構造Hash
,您可以在收集值時獲得performance
增益,例如:
require 'benchmark'
members_without_sym = {"total"=>3, "data"=>[
{"email"=>"foo@example.org", "timestamp"=>"2013-03-16 01:11:01"},
{"email"=>"bar@example.org", "timestamp"=>"2013-03-16 02:07:30"},
{"email"=>"exx@example.org", "timestamp"=>"2013-03-16 03:06:24"}
]}
members_with_sym = {:total=>3, :data=>[
{:email=> "foo@example.org", :timestamp => "2013-03-16 01:11:01"},
{:email=> "bar@example.org", :timestamp => "2013-03-16 02:07:30"},
{:email=> "exx@example.org", :timestamp=> "2013-03-16 03:06:24"}
]}
Benchmark.bm(1) do |algo|
algo.report("Without symbol"){
2_000_000.times do
members_without_sym['data'].collect { |h| h['email'] }
end
}
algo.report("With symbol"){
2_000_000.times do
members_with_sym[:data].collect { |h| h[:email] }
end
}
end
結果:
user system total real
Without symbol 2.260000 0.000000 2.260000 ( 2.254277)
With symbol 0.880000 0.000000 0.880000 ( 0.878603)
除了將h['email']
部分優化為原生擴展之外,我無法看到如何使上述示例更有效。 這樣做的效率增益對於數據集的示例大小來說是微不足道的,並且比我首先想到的優化獲取/解析這些數據的I / O要小得多。
根據您的數據源,將散列鍵作為標簽而不是字符串,是一種常見的Ruby習慣用法,並且在內存使用方面也更有效。 這可能是效率的更大提升,並且可能是值得的,只要您不必花費大量精力來轉換數據(例如,您可以以某種方式改變數據源中給定數據結構的性質,無需轉換哈希只是查詢一次!)
members = {"total"=>3, "data"=>[
{"email"=>"foo@example.org", "timestamp"=>"2013-03-16 01:11:01"},
{"email"=>"bar@example.org", "timestamp"=>"2013-03-16 02:07:30"},
{"email"=>"exx@example.org", "timestamp"=>"2013-03-16 03:06:24"}
]}
temp = members["data"].map{|x|x["email"]}
給你[“foo@example.org”,“bar @ example.org”,“exx@example.org”]
-
也許Structs可以提高性能
Record = Struct.new(:email, :timestamp)
members = {"total"=>3, "data"=>[
Record.new("foo@example.org","2013-03-16 01:11:01"),
Record.new("bar@example.org","2013-03-16 02:07:30"),
Record.new("exx@example.org","2013-03-16 03:06:24")
]}
temp = members["data"].map(&:email)
http://blog.rubybestpractices.com/posts/rklemme/017-Struct.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.