如何从哈希中的字符串中删除空格

时间:2016-12-09 15:29:30

标签: ruby hash

这是我的榜样:

hash = {"buy"=>"Buy ", "quantity"=>"3 ", "get"=>"Get ", "reward"=>"1 ", "free"=>"Free"}

def stripit(value)
  #value.gsub!('B', 'C')
  value.gsub!('/\s+/', '')
  value
end

newhash = hash.update(hash){|key,value| stripit(value)}
puts newhash.inspect

gsub处理该值 - 第一个评论的替换工作 - 但由于某种原因,它不会删除空格。

如何从哈希值中删除空格?

5 个答案:

答案 0 :(得分:8)

您可以使用each方法和strip!修改哈希值。

hash = {"buy"=>"Buy ", "quantity"=>"3 ", "get"=>"Get ", "reward"=>"1 ", "free"=>"Free"}

hash.each_value(&:strip!)

p hash
# => {"buy"=>"Buy", "quantity"=>"3", "get"=>"Get", "reward"=>"1", "free"=>"Free"}

答案 1 :(得分:3)

我认为问题在于您已将正则表达式包装在引号中,因此它与您期望的方式不匹配!

value.gsub!(/\s+/, '')

(编辑:完整代码,复制原始问题'代码但改变gsub!参数。使用ruby 2.3.1测试)

hash = {"buy"=>"Buy ", "quantity"=>"3 ", "get"=>"Get ", "reward"=>"1 ", "free"=>"Free"}

def stripit(value)
  value.gsub!(/\s+/, '')
  value
end

newhash = hash.update(hash){|key,value| stripit(value)}
puts newhash.inspect

输出:

{"buy"=>"Buy", "quantity"=>"3", "get"=>"Get", "reward"=>"1", "free"=>"Free"}

答案 2 :(得分:1)

如果你想得到一个new_hash而不是修改原来的那个:

new_hash = hash.map{|k,v| [k,v.gsub(/\s+/,'')]}.to_h

使用Rails或ActiveSupport extensions,它变得更短:

hash.transform_values{|v| v.gsub(/\s+/,'')}

注意:它会删除值中的任何空格。 "Get A "将转换为"GetA"String#strip只会将其转换为"Get A"

答案 3 :(得分:0)

如果您将value(或仅stripit)替换为v.gsub!(/\s+/, ''),则/\s/中不需要v.gsub(/\s/, '')行。这是允许的(并且首选,imo,为了更好的可读性并保存一行代码),因为Hash#update(aka merge!)正在处理就地替换。 (读者:提问者有value行,因为String#gsub!在未进行任何更改时会返回nil

你可能想要在尝试替换之前确认哈希值是一个字符串(除非你确定,即使将来,也永远不会有一个不是字符串的值,但即便如此,检查也没有坏处)。

我建议如下。

hash = {"buy"=>"Buy It ", "quantity"=>"3 ", "get"=>"Get ", "reward"=>"1 ",
        "free"=>"Free", "THE answer"=> 42 }

如果hash不被改变:

hash.merge(hash) { |_,v,_| v.is_a?(String) ? v.gsub(/\s/, '') : v }
  #=> {"buy"=>"BuyIt", "quantity"=>"3", "get"=>"Get", "reward"=>"1", "free"=>"Free"} 
hash
  #=> {"buy"=>"Buy It ", "quantity"=>"3 ", "get"=>"Get ", "reward"=>"1 ",
  #    "free"=>"Free", "THE answer"=>42} 

如果要变异hash

hash.update(hash) { |_,v,_| v.is_a?(String) ? v.gsub(/\s/, '') : v }
  #=> {"buy"=>"BuyIt", "quantity"=>"3", "get"=>"Get", "reward"=>"1",   
  #    "free"=>"Free", "THE answer"=>42} 
hash
  #=> {"buy"=>"BuyIt", "quantity"=>"3", "get"=>"Get", "reward"=>"1",
  #    "free"=>"Free", "THE answer"=>42} 

这使用Hash#mergeHash#update的形式,它们使用块来确定合并的两个哈希中存在的键的值。这当然是所有的钥匙。有关详细信息,请参阅文档,尤其是三个块变量的含义。 (我用下划线表示三个块变量中的两个,表示它们没有用于块计算。)

另一种方式

如果hash不被改变:

hash.keys.each_with_object({}) do |k,h|
  v = hash[k]
  h[k] = v.is_a?(String) ? v.gsub(/\s/, '') : v
end
  #=> {"buy"=>"BuyIt", "quantity"=>"3", "get"=>"Get", "reward"=>"1",
  # "free"=>"Free", "THE answer"=>42} 

hash
  #=> {"buy"=>"Buy It ", "quantity"=>"3 ", "get"=>"Get ", "reward"=>"1 ",
  #    "free"=>"Free", "THE answer"=>42} 

如果要改变hash

hash.keys.each do |k|
  v = hash[k]
  hash[k] = v.is_a?(String) ? v.gsub(/\s/, '') : v
end
  #=> ["buy", "quantity", "get", "reward", "free", "THE answer"]
hash
  #=> {"buy"=>"BuyIt", "quantity"=>"3", "get"=>"Get", "reward"=>"1",
  #    "free"=>"Free", "THE answer"=>42} 

请注意,在最后一种情况下,hash已发生变异,但该块未返回更新的hash

答案 4 :(得分:0)

您还可以将map bang 运算符一起使用,如下所示:

hash.values.map! {|value| value.strip!}