English 中文(简体)
如何将鲁比拉的 has中的所有钥匙推高? [复制]
原标题:How to elegantly rename all keys in a hash in Ruby? [duplicate]
  • 时间:2010-11-09 19:48:32
  •  标签:
  • ruby
  • hash
  • key

我有一个Ruby。

ages = { "Bruce" => 32,
         "Clark" => 28
       }

Assuming I have another hash of replacement names, is there an elegant way to rename all the keys so that I end up with:

ages = { "Bruce Wayne" => 32,
         "Clark Kent" => 28
       }
最佳回答
ages = {  Bruce  => 32,  Clark  => 28 }
mappings = {  Bruce  =>  Bruce Wayne ,  Clark  =>  Clark Kent  }

ages.transform_keys(&mappings.method(:[]))
#=> {  Bruce Wayne  => 32,  Clark Kent  => 28 }
问题回答

我喜欢Jörg W Mittag的回答,但如果你想要重新命名你目前的哈希和的钥匙,而不是以更名的钥匙创建新的《哈希,那么,以下几句其实是:

ages = { "Bruce" => 32, "Clark" => 28 }
mappings = {"Bruce" => "Bruce Wayne", "Clark" => "Clark Kent"}

ages.keys.each { |k| ages[ mappings[k] ] = ages.delete(k) if mappings[k] }
ages

此外,只有重新命名必要的钥匙才有好处。

业绩考量:

根据, 丁曼回答,我的回答是得更快<>20%,而不是Jörg W Mittag对哈希的答复,只有两个钥匙。 有许多钥匙的哈希斯人的业绩可能更高,特别是只有几个关键人物改名。

使用的<代码>each_with_object 鲁比也采用的方法:

ages = { "Bruce" => 32, "Clark" => 28 }
mappings = { "Bruce" => "Bruce Wayne", "Clark" => "Clark Kent" }

ages.each_with_object({}) { |(k, v), memo| memo[mappings[k]] = v }

更快速的是:

require  fruity 

AGES = { "Bruce" => 32, "Clark" => 28 }
MAPPINGS = {"Bruce" => "Bruce Wayne", "Clark" => "Clark Kent"}

def jörg_w_mittag_test(ages, mappings)
  Hash[ages.map {|k, v| [mappings[k], v] }]
end

require  facets/hash/rekey 
def tyler_rick_test(ages, mappings)
  ages.rekey(mappings)
end

def barbolo_test(ages, mappings)
  ages.keys.each { |k| ages[ mappings[k] ] = ages.delete(k) if mappings[k] }
  ages
end

class Hash
  def tfr_rekey(h)
    dup.tfr_rekey! h
  end

  def tfr_rekey!(h)
    h.each { |k, newk| store(newk, delete(k)) if has_key? k }
    self
  end
end

def tfr_test(ages, mappings)
  ages.tfr_rekey mappings
end

class Hash
  def rename_keys(mapping)
    result = {}
    self.map do |k,v|
      mapped_key = mapping[k] ? mapping[k] : k
      result[mapped_key] = v.kind_of?(Hash) ? v.rename_keys(mapping) : v
      result[mapped_key] = v.collect{ |obj| obj.rename_keys(mapping) if obj.kind_of?(Hash)} if v.kind_of?(Array)
    end
    result
  end
end

def greg_test(ages, mappings)
  ages.rename_keys(mappings)
end

compare do
  jörg_w_mittag { jörg_w_mittag_test(AGES.dup, MAPPINGS.dup) }
  tyler_rick    { tyler_rick_test(AGES.dup, MAPPINGS.dup)    }
  barbolo       { barbolo_test(AGES.dup, MAPPINGS.dup)       }
  greg          { greg_test(AGES.dup, MAPPINGS.dup)          }
end

哪些产出:

Running each test 1024 times. Test will take about 1 second.
barbolo is faster than jörg_w_mittag by 19.999999999999996% ± 10.0%
jörg_w_mittag is faster than greg by 10.000000000000009% ± 10.0%
greg is faster than tyler_rick by 30.000000000000004% ± 10.0%

<Caution:barbell s Solutions used ifographys[k],如果mppings [k]成形,就会使由此产生的散列错。

I monkey-sued the category to Address nested Hashes and Arrays:

   #  Netsted Hash:
   # 
   #  str_hash = {
   #                "a"  => "a val", 
   #                "b"  => "b val",
   #                "c" => {
   #                          "c1" => "c1 val",
   #                          "c2" => "c2 val"
   #                        }, 
   #                "d"  => "d val",
   #           }
   #           
   # mappings = {
   #              "a" => "apple",
   #              "b" => "boss",
   #              "c" => "cat",
   #              "c1" => "cat 1"
   #           }
   # => {"apple"=>"a val", "boss"=>"b val", "cat"=>{"cat 1"=>"c1 val", "c2"=>"c2 val"}, "d"=>"d val"}
   #
   class Hash
    def rename_keys(mapping)
      result = {}
      self.map do |k,v|
        mapped_key = mapping[k] ? mapping[k] : k
        result[mapped_key] = v.kind_of?(Hash) ? v.rename_keys(mapping) : v
        result[mapped_key] = v.collect{ |obj| obj.rename_keys(mapping) if obj.kind_of?(Hash)} if v.kind_of?(Array)
      end
    result
   end
  end

If the mapping Hash will be smaller than the data Hash then iterate on mappings instead. This is useful for renaming a few fields in a large Hash:

class Hash
  def rekey(h)
    dup.rekey! h
  end

  def rekey!(h)
    h.each { |k, newk| store(newk, delete(k)) if has_key? k }
    self
  end
end

ages = { "Bruce" => 32, "Clark" => 28, "John" => 36 }
mappings = {"Bruce" => "Bruce Wayne", "Clark" => "Clark Kent"}
p ages.rekey! mappings

的关键方法。

只要你依靠https://github.com/rubywork/facets” rel=“nofollow” 标题=“Facets”gem,你就可以将制图的散射线通过到rekey,并将把新的散射线带回:

require  facets/hash/rekey 
ages = { "Bruce" => 32, "Clark" => 28 }
mappings = {"Bruce" => "Bruce Wayne", "Clark" => "Clark Kent"}
ages.rekey(mappings)
=> {"Bruce Wayne"=>32, "Clark Kent"=>28}

如果你想要修改年龄,你可以使用<代码>rekey!。 文本:

ages.rekey!(mappings)
ages
=> {"Bruce Wayne"=>32, "Clark Kent"=>28}
ages = { "Bruce" => 32, "Clark" => 28 }
mappings = {"Bruce" => "Bruce Wayne", "Clark" => "Clark Kent"}
ages = mappings.inject({}) {|memo, mapping| memo[mapping[1]] = ages[mapping[0]]; memo}
puts ages.inspect
>> x={ :a =>  qwe , :b =>  asd }
=> {:a=>"qwe", :b=>"asd"}
>> rename={:a=>:qwe}
=> {:a=>:qwe}
>> rename.each{|old,new| x[new] = x.delete old}
=> {:a=>:qwe}
>> x
=> {:b=>"asd", :qwe=>"qwe"}

这只是通过更名的散射。

我利用这一方法,允许在库克表格中的“友好”名字被划为一类特性,因此工厂女童可以树立一个榜样:

Given(/^an organization exists with the following attributes:$/) do |table|
  # Build a mapping from the "friendly" text in the test to the lower_case actual name in the class
  map_to_keys = Hash.new
  table.transpose.hashes.first.keys.each { |x| map_to_keys[x] = x.downcase.gsub(   ,  _ ) }
  table.transpose.hashes.each do |obj|
    obj.keys.each { |k| obj[map_to_keys[k]] = obj.delete(k) if map_to_keys[k] }
    create(:organization, Rack::Utils.parse_nested_query(obj.to_query))
  end
end

木板表认为:

  Background:
    And an organization exists with the following attributes:
      | Name            | Example Org                        |
      | Subdomain       | xfdc                               |
      | Phone Number    | 123-123-1234                       |
      | Address         | 123 E Walnut St, Anytown, PA 18999 |
      | Billing Contact | Alexander Hamilton                 |
      | Billing Address | 123 E Walnut St, Anytown, PA 18999 |

And map_to_keys looks:

{
               "Name" => "name",
          "Subdomain" => "subdomain",
       "Phone Number" => "phone_number",
            "Address" => "address",
    "Billing Contact" => "billing_contact",
    "Billing Address" => "billing_address"
}




相关问题
Ruby parser in Java

The project I m doing is written in Java and parsers source code files. (Java src up to now). Now I d like to enable parsing Ruby code as well. Therefore I am looking for a parser in Java that parses ...

rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...

RubyCAS-Client question: Rails

I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

multiple ruby extension modules under one directory

Can sources for discrete ruby extension modules live in the same directory, controlled by the same extconf.rb script? Background: I ve a project with two extension modules, foo.so and bar.so which ...

Text Editor for Ruby-on-Rails

guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...

热门标签