Ruby变换哈希基于映射

时间:2016-08-12 20:37:22

标签: ruby hash rename

假设我有一个关于我想要一个哈希结果的映射,以及这样的新密钥名称:

JSON_MAP = {
  image: {
    id: :id,
    media_url: :url,
    time: :duration,
    timestamp: :time_posted,
    text_caption: :caption,
    metadata: {
      camera: :camera_type,
      flash: :camera_flash
    }
  },
  viewers: {
    views: :view_count,
    likes: :likes_count
  }
}

我有这样的哈希:

{
  image: {
    id: 1,
    media_url: 'http://placekitten.com',
    nsfw: false,
    time: 4,
    timestamp: 14149292,
    text_caption: "I'm a kitten",
    metadata: {
      camera: 'iPhone',
      flash: true
    }
  },
  viewers: {
    views: 50,
    likes: 15
  },
  extras: {
    features: {
      enabled: true
    }
  }
}

我只希望它转换数据,最终结果如下:

{
  image: {
    id: 1,
    url: 'http://placekitten.com',
    duration: 4,
    time_posted: 14149292,
    caption: "I'm a kitten",
    metadata: {
      camera: 'iPhone',
      flash: true
    }
  },
  viewers: {
    view_count: 50,
    likes_count: 15
  }
}

基本上,根据源地图重命名所有键,并删除与源地图不匹配的任何键......

1 个答案:

答案 0 :(得分:1)

您可以使用递归获得所需的结果。

def convert(mapper, hsh)
  mapper.each_with_object({}) do |(k,o),h|
    next unless hsh.key?(k)
    if o.is_a? Hash
      h[k] = convert(o, hsh[k])
    else
      h[o] = hsh[k]
    end
  end
end

假设h等于你的第二个哈希,

convert(JSON_MAP, h)    
  #=> { :image=>{
  #       :id=>1,
  #       :url=>"http://placekitten.com",
  #       :duration=>4,
  #       :time_posted=>14149292,
  #       :caption=>"I'm a kitten",
  #       :metadata=>{
  #         :camera_type=>"iPhone",
  #         :camera_flash=>true
  #       }
  #     },
  #     :viewers=>{
  #       :view_count=>50,
  #       :likes_count=>15
  #     }
  #   }