5

Ruby で次のようなハッシュがあるとします。

{ :ie0 => "Hi",    :ex0 => "Hey",       :eg0 => "Howdy", 
  :ie1 => "Hello", :ex1 => "Greetings", :eg1 => "Good day"}

それを次のようなものに変える良い方法は何ですか:

{ "0" => 
    { 
        "ie" => "Hi", "ex" => "Hey", "eg" => "Howdy"
    },
  "1" => 
    {
        "ie" => "Hello", "ex" => "Greetings", "eg" => "Good day"
    }
}
4

5 に答える 5

3

きれいではありませんが、これは機能します:

input = { :ie0 => "Hi",    :ex0 => "Hey",       :eg0 => "Howdy",
          :ie1 => "Hello", :ex1 => "Greetings", :eg1 => "Good day"}

output = input.inject({}) do |result, item|
  item[0] =~ /(?<key>[^\d]+)(?<index>\d+)/
  key, index = $1, $2
  value = item[1]

  result[index] ||= {}
  result[index].merge! { key => value }
  result
end

puts output
于 2013-10-05T03:18:42.327 に答える
2
require 'awesome_print'

hsh = {
           :ie0 => "Hi",
           :ex0 => "Hey",
           :eg0 => "Howdy",
           :ie1 => "Hello",
           :ex1 => "Greetings",
           :eg1 => "Good day"
      }

new_hsh = hsh.each_with_object(Hash.new { |h, k| h[k] = { } }) do |(k,v),h|
       h[k[-1]].merge!({k[0..-2] => v})
end
ap new_hsh

出力 (でフォーマットawesome_print)

{
    "0" => {
        "ie" => "Hi",
        "ex" => "Hey",
        "eg" => "Howdy"
    },
    "1" => {
        "ie" => "Hello",
        "ex" => "Greetings",
        "eg" => "Good day"
    }
}
于 2013-10-05T05:18:46.803 に答える
1

編集:賛成票を投じた方にお詫び申し上げます。その歴史的重要性のために (そしてもちろん 10 ポイントのために) ここに残します。その多くの欠点の中でも、結果で許可されるのは 1 桁のキーのみです。私はもっ​​と好きな別の解決策を提出しました。

h = {ie0: "Hi", ex0: "Hey", eg0: "Howdy", ie1: "Hello", ex1: "Greetings", eg1: "Good day"}

n = h.keys.map {|k| k.to_s[0..-2]}.uniq.size # => 3

Hash[*h.to_a.each_slice(n).to_a.map {|s| [s.first.first.to_s[-1], Hash[*s.map {|v| [v.first.to_s[0..-2], v.last]}.flatten]]}.flatten]
于 2013-10-05T04:36:25.153 に答える