映射哈希表的键

15
我正在使用一个名为 my_hash 的哈希表:
{"2011-02-01 00:00:00+00"=>816, "2011-01-01 00:00:00+00"=>58, "2011-03-01 00:00:00+00"=>241}

首先,我尝试解析my_hash中的所有键(它们都是时间)。
my_hash.keys.sort.each do |key|
  parsed_keys << Date.parse(key).to_s
end 

这给我带来了以下结果:
["2011-01-01", "2011-02-01", "2011-03-01"]

然后,我尝试将parsed_keys映射回到my_hash的键:

Hash[my_hash.map {|k,v| [parsed_keys[k], v]}]

但是这将返回以下错误:
TypeError: can't convert String into Integer

我该如何将parsed_keys映射回my_hash的键?
我的目标是摆脱所有键末尾的“00:00:00+00”。

1
问题在于parsed_keys是一个数组,而parsed_keys[k]正在索引到一个数组中,因此Ruby希望您使用索引而不是字符串。如果您真的想保持代码不变,请将parsed_keys也设置为哈希,并像这样设置:parsed_keys[key] = Date.parse(key).to_s - MrDanA
让我试试这个。非常感谢! - Myxtic
5个回答

28

为什么不直接这样做呢?

my_hash.map{|k,v| {k.gsub(" 00:00:00+00","") => v}}.reduce(:merge)

这将提供给您

{"2011-02-01"=>816, "2011-01-01"=>58, "2011-03-01"=>241}

是的,那是个好主意。但有些地方字符串是“00:00:00”,而其他地方是“00:00:00+00”。我能否使用同一段代码摆脱这两个字符串? - Myxtic
尝试使用正则表达式。my_hash.map{|k,v| {k.gsub(/ .+$/,"") => v}}.reduce(:merge)这将删除空格后的所有内容。 - iblue

6

3

另一种选择可能是:

  1. 映射(map)
  2. 返回转换后的两个元素数组 [converted_key, converted_value]
  3. 再将其转换回哈希表
irb(main):001:0> {a: 1, b: 2}.map{|k,v| [k.to_s, v.to_s]}.to_h               
=> {"a"=>"1", "b"=>"2"}   

3

使用 iblue 的答案,你可以使用正则表达式来处理这种情况,例如:

pattern = /00:00:00(\+00)+/
my_hash.map{|k,v| {k.gsub(pattern,"") => v}}.reduce(:merge)

您可以改进这个模式,以处理不同的情况。

希望能对您有所帮助。

编辑:

抱歉,iblue已经发布了答案。


这将在键(`"2011-01-01 ")留下一个空格。 - iblue
没错,你说得对,模式应该是 / 00:00:00(+00)+/ :) - Juan de Dios H.
感谢您提供的另一种解决方案,Juan。 - Myxtic

0
使用 Ruby 标准库中的 Hash#transform_keys 方法。
my_hash.transform_keys { |key| key.gsub(" 00:00:00+00", "") }

Hash#transform_keys可用时

该方法是在标准库中添加的Ruby 2.5,发布于2017年12月25日。 Hash#transform_keys也曾在Active Support中定义,从Rails 4.0.1(发布于2013年11月1日)开始。Active Support对该方法的定义在Rails 6.0中被移除,因为在Rails 6.0中依赖于Ruby 2.5,所以不再需要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接