【问题标题】:How to get a specific output iterating a hash in Ruby?如何在 Ruby 中获取迭代哈希的特定输出?
【发布时间】:2010-11-16 16:30:20
【问题描述】:

我想获得一个迭代 Ruby 哈希的特定输出。

这是我要迭代的哈希:

hash = {
  1 => ['a', 'b'], 
  2 => ['c'], 
  3 => ['d', 'e', 'f', 'g'], 
  4 => ['h']
}

这是我想要得到的输出:

1-----

a

b

2-----

c

3-----

d 

e

f

g

4-----

h

在 Ruby 中,如何使用 Hash 获得这样的输出?

【问题讨论】:

  • 如果你正在迭代一个哈希并期望它被排序,你可能需要使用一些其他的集合类型
  • 我可以将哈希值作为单选按钮选项传递吗??
  • 我将哈希作为单选按钮选项传递.. 但对于第一个选项,我得到单选按钮,对于其他值没有得到它。
  • @Allen:哈希在 Ruby 1.9 中排序。如果您使用的是 Ruby culann.com/2008/01/rails-goodies-activesupportorderedhash

标签: ruby hash output


【解决方案1】:
hash.each do |key, array|
  puts "#{key}-----"
  puts array
end

关于我应该补充的顺序,在 1.8 中,项目将以随机顺序迭代(嗯,实际上是按照 Fixnum 的散列函数定义的顺序),而在 1.9 中,它将按照文字的顺序进行迭代。

【讨论】:

  • 如果密钥没有在任何地方使用怎么办? .我们需要用? 代替 key 吗?例如:|?, array| 这是有效的语法吗?
  • @huzefabiyawarwala 不,? 在 Ruby 中不是有效的变量名。你可以使用_,但你不需要
  • @huzefabiyawarwala 是的,你可以写|_, v|
  • 什么用变量名数组代替v或value?
  • @jrhicks 因为 OP 有一个哈希值是数组。
【解决方案2】:

遍历哈希的最基本方法如下:

hash.each do |key, value|
  puts key
  puts value
end

【讨论】:

  • 是的,这是有道理的。为什么@sepp2k 的答案键上有一个#{}?
  • 哦,没关系。我看到它是用于字符串插值
【解决方案3】:
hash.keys.sort.each do |key|
  puts "#{key}-----"
  hash[key].each { |val| puts val }
end

【讨论】:

    【解决方案4】:

    对哈希调用排序会将其转换为嵌套数组,然后按键对其进行排序,因此您只需要这样:

    puts h.sort.map {|k,v| ["#{k}----"] + v}
    

    如果您实际上不需要“----”部分,则可以:

    puts h.sort
    

    【讨论】:

    • 哈希键是数字,所以 '[k + "----"]' 会引发 TypeError(不能将字符串强制转换为 Fixnum)。你需要'[k.to_s + "----"]'
    • 确实如此。我的测试版中有字母。已修复,使用更好的“#{k}----”。
    【解决方案5】:

    我的单行解决方案:

    hash.each { |key, array| puts "#{key}-----", array }

    我认为它很容易阅读。

    【讨论】:

      【解决方案6】:

      您还可以refine Hash::each,使其支持递归枚举。这是我的 Hash::each(Hash::each_pair) 版本,支持 blockenumerator

      module HashRecursive
          refine Hash do
              def each(recursive=false, &block)
                  if recursive
                      Enumerator.new do |yielder|
                          self.map do |key, value|
                              value.each(recursive=true).map{ |key_next, value_next| yielder << [[key, key_next].flatten, value_next] } if value.is_a?(Hash)
                              yielder << [[key], value]
                          end
                      end.entries.each(&block)
                  else
                      super(&block)
                  end
              end
              alias_method(:each_pair, :each)
          end
      end
      
      using HashRecursive
      

      以下是Hash::each 使用和不使用recursive 标志的示例

      hash = {
          :a => {
              :b => {
                  :c => 1,
                  :d => [2, 3, 4]
              },
              :e => 5
          },
          :f => 6
      }
      
      p hash.each, hash.each {}, hash.each.size
      # #<Enumerator: {:a=>{:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}, :f=>6}:each>
      # {:a=>{:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}, :f=>6}
      # 2
      
      p hash.each(true), hash.each(true) {}, hash.each(true).size
      # #<Enumerator: [[[:a, :b, :c], 1], [[:a, :b, :d], [2, 3, 4]], [[:a, :b], {:c=>1, :d=>[2, 3, 4]}], [[:a, :e], 5], [[:a], {:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}], [[:f], 6]]:each>
      # [[[:a, :b, :c], 1], [[:a, :b, :d], [2, 3, 4]], [[:a, :b], {:c=>1, :d=>[2, 3, 4]}], [[:a, :e], 5], [[:a], {:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}], [[:f], 6]]
      # 6
      
      hash.each do |key, value|
          puts "#{key} => #{value}"
      end
      # a => {:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}
      # f => 6
      
      hash.each(true) do |key, value|
          puts "#{key} => #{value}"
      end
      # [:a, :b, :c] => 1
      # [:a, :b, :d] => [2, 3, 4]
      # [:a, :b] => {:c=>1, :d=>[2, 3, 4]}
      # [:a, :e] => 5
      # [:a] => {:b=>{:c=>1, :d=>[2, 3, 4]}, :e=>5}
      # [:f] => 6
      
      hash.each_pair(recursive=true) do |key, value|
          puts "#{key} => #{value}" unless value.is_a?(Hash)
      end
      # [:a, :b, :c] => 1
      # [:a, :b, :d] => [2, 3, 4]
      # [:a, :e] => 5
      # [:f] => 6
      

      这是问题本身的示例:

      hash = {
          1   =>  ["a", "b"], 
          2   =>  ["c"], 
          3   =>  ["a", "d", "f", "g"], 
          4   =>  ["q"]
      }
      
      hash.each(recursive=false) do |key, value|
          puts "#{key} => #{value}"
      end
      # 1 => ["a", "b"]
      # 2 => ["c"]
      # 3 => ["a", "d", "f", "g"]
      # 4 => ["q"]
      

      还可以看看我的递归版本Hash::merge(Hash::merge!)here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-13
        • 1970-01-01
        • 2015-08-30
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多