在ruby中将哈希转换为数组

时间:2018-04-19 15:30:29

标签: ruby-on-rails ruby ruby-on-rails-4

我需要下一个哈希:

x = {
  params: {
    user_params1: { name: "stephen", dir: "2001", dir2: nil },
    user_params2: { name: "josh", dir: "jhon", dir2: nil }
}

返回一个新的数组哈希:

x = {
  params: {
    user_params1: ["stephen","201", ""],
    user_params2: ["josh","jhon",""]
}

2 个答案:

答案 0 :(得分:1)

假设:

x = {
      params: {
        user_params1: { name: "stephen", dir: "2001", dir2: nil },
        user_params2: { name: "josh", dir: "jhon", dir2: nil }
      }
    }

尝试:

x[:params] = x[:params].each_with_object({}) do |(k,v), returning|
  returning[k] = v.map{|k,v| v}
end

将产生:

{:params=>{:user_params1=>["stephen", "2001", nil], :user_params2=>["josh", "jhon", nil]}}

如果你想要空字符串而不是nils(如你的例子中所示),请执行:

x[:params] = x[:params].each_with_object({}) do |(k,v), returning|
  returning[k] = v.map{|k,v| v.to_s}
end

如果您不想修改x,那么只需创建一个新的hash并执行相同操作:

y ={}
y[:params] = x[:params].each_with_object({}) do |(k,v), returning|
  returning[k] = v.map{|k,v| v.to_s}
end

由于您未对k中的v.map做任何事情,您可以v.values.map(&:to_s)(从Gerry的回答中无耻地偷走) - 这是更清洁,国际海事组织,但你需要额外的一个字符(!) - 并最终得到:

y ={}
y[:params] = x[:params].each_with_object({}) do |(k,v), returning|
  returning[k] = v.values.map(&:to_s)
end

正如塞巴斯蒂安指出的那样,有这样的语法糖:

y[:params] = x[:params].transform_values do |value|
  # Then use one of:
  #   hash.values.map { |value| value.nil? ? '' : value }
  #   hash.values.map { |value| value ? value : '' }
  #   hash.values.map { |value| value || '' }
  #   hash.values.map(&:to_s)      
end

有趣的是,如果你看一下source code, 您会发现each_with_objecttranform_values机制非常相似:

def transform_values
  return enum_for(:transform_values) unless block_given?
  result = self.class.new
  each do |key, value|
    result[key] = yield(value)
  end
  result
end

你可以想象这被重写为:

def transform_values
  return enum_for(:transform_values) unless block_given?
  each_with_object(self.class.new) do |(key, value), result|
    result[key] = yield(value)
  end
end

其根源(IMO)几乎就是格里和我提出的。

对我来说,这只猫的皮肤很好。

答案 1 :(得分:0)

你使用project-two(两次以防你在顶层有一把钥匙);例如:

each_with_object