使用散列中的值替换散列中的键

时间:2013-01-08 18:40:51

标签: ruby regex

我有一个哈希(有数百对),我有一个字符串。

我希望在此字符串中将所有出现的键从哈希替换为哈希值。

我明白我可以做这样的事情

some_hash.each { |key, value| str = str.gsub(key, value) }

但是,我想知道是否有更好的(表现明智的)方法来做到这一点。

2 个答案:

答案 0 :(得分:5)

您只需要运行gsub一次。由于正则表达式(oniguruma)是用C实现的,所以它应该比在Ruby中循环更快。

some_hash = {
  "a" => "A",
  "b" => "B",
  "c" => "C",
}

"abcdefgabcdefg".gsub(Regexp.union(some_hash.keys), some_hash)
# => "ABCdefgABCdefg"

答案 1 :(得分:2)

一些基准:

require 'benchmark'

SOME_HASH = Hash[('a'..'z').zip('A'..'Z')]
SOME_REGEX = Regexp.union(SOME_HASH.keys)

SHORT_STRING = ('a'..'z').to_a.join
LONG_STRING = SHORT_STRING * 100

N = 10_000

def sub1(str)
  SOME_HASH.each { |key, value|
    str = str.gsub(key, value) 
  } 
  str
end

def sub2(str)
  SOME_HASH.each { |key, value|
    str.gsub!(key, value) 
  } 
  str
end

def sub_regex(str)
  str.gsub(SOME_REGEX, SOME_HASH)
end

puts RUBY_VERSION
puts "#{ N } loops"
puts
puts "sub1: #{ sub1(SHORT_STRING) }"
puts "sub2: #{ sub2(SHORT_STRING) }"
puts "sub_regex: #{ sub_regex(SHORT_STRING) }"
puts

Benchmark.bm(10) do |b|

  b.report('gsub')  { N.times { sub1(LONG_STRING)      } }
  b.report('gsub!') { N.times { sub2(LONG_STRING)      } }
  b.report('regex') { N.times { sub_regex(LONG_STRING) } }

end

哪个输出:

1.9.3
10000 loops

sub1: ABCDEFGHIJKLMNOPQRSTUVWXYZ
sub2: ABCDEFGHIJKLMNOPQRSTUVWXYZ
sub_regex: ABCDEFGHIJKLMNOPQRSTUVWXYZ

                user     system      total        real
gsub        14.360000   0.030000  14.390000 ( 14.412178)
gsub!        1.940000   0.010000   1.950000 (  1.957591)
regex        0.080000   0.000000   0.080000 (  0.075038)