我需要下一个散列:
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",""]
}
最佳答案
给定:
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
因为你没有对 v.map
中的 k
做任何事情,你可以只做 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
正如 Sebastian 指出的那样,这里有语法糖:
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_object
和 tranform_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),这几乎就是 Gerry 和我想出的。
我觉得这只猫的皮肤很好。
关于ruby-on-rails - 在 ruby 中将散列转换为数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49924891/