Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何有效地从散列中提取具有特定键名的所有值?_Ruby_Arrays_Hash - Fatal编程技术网

Ruby 如何有效地从散列中提取具有特定键名的所有值?

Ruby 如何有效地从散列中提取具有特定键名的所有值?,ruby,arrays,hash,Ruby,Arrays,Hash,我有以下数据: 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

我有以下数据:

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。

    除了将
    h['email']
    部分优化为本机扩展之外,我不知道如何使上述示例更有效。这样做的效率增益对于数据集的示例大小来说是微乎其微的,远远低于我最初怀疑的优化获取/解析这些数据的I/O

    根据您的数据源,将散列键作为标签而不是字符串是一种常见的Ruby习惯用法,而且在内存使用方面也更有效。这可能会提高效率,如果您不必花费大量精力转换数据(例如,您可以通过某种方式从数据源更改给定数据结构的性质,而无需转换哈希值来查询一次),那么这可能是值得的

    给你[”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)
    

    除其他答案外,如果您能够使用
    符号
    作为
    键来构建
    哈希
    ,我将添加
    属性,您可以在收集值时获得
    性能
    增益,例如:

    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)
    

    数据来自MailChimp API,所以我想我们无法利用这种情况下的符号。无论如何+1数据来自MailChimp API,所以我想我们无法利用这种情况下的符号。还感谢您指出基准类-在未来将非常有用+1虽然按符号查找比按字符串查找确实快得多,但您的基准测试并不能证明这一点。在时间测量中存在着明显的抖动,而像这样尝试进行基准测试的单个迭代不太可能有意义(请注意,您的用户时间是相同的,为0)。作为一般规则,您应该尝试在基准测试下对计算的N次迭代进行计时,其中N的大小足以在一秒钟内完成整个计时。在我的机器上,这是200万次迭代的顺序:
    2000000。次{members\u without\u sym['data']}。collect{h{h}h['email']}
    @dbenhur谢谢你指出,我刚刚更新了代码。没错,
    map
    collect
    +1:]短。我说的是“短”,实际上意思是“更不复杂”-就像没有块的变体一样。您可能会对结构b感兴趣:)
            user     system      total        real
    Without symbol  2.260000   0.000000   2.260000 (  2.254277)
    With symbol  0.880000   0.000000   0.880000 (  0.878603)