切片字与前一个字符

时间:2015-03-09 11:58:20

标签: ruby word

有没有更好的方法在红宝石中切一个单词? 我的解决方案:

str="TAMILNADU"
pairs=[]
numPairs= str.length-1
i=0
while i<numPairs do 
  pairs[i] = str.slice(i,2)
  i+=1
end

结果

["TA", "AM", "MI", "IL", "LN", "NA", "AD", "DU"] 

5 个答案:

答案 0 :(得分:10)

是的,有:

irb(main):001:0> "TAMILNADU".chars.each_cons(2).map(&:join)
=> ["TA", "AM", "MI", "IL", "LN", "NA", "AD", "DU"]

请参阅the documentation of Enumerable#each_cons

答案 1 :(得分:4)

另一个使用积极前瞻的人:

str = 'TAMILNADU'
str.scan(/(.)(?=(.))/).map(&:join)
#=> ["TA", "AM", "MI", "IL", "LN", "NA", "AD", "DU"]

答案 2 :(得分:1)

另一个版本:

str = "TAMILNADU"

(0...str.size-1).map{|x| str[x,2]} 
# => ["TA", "AM", "MI", "IL", "LN", "NA", "AD", "DU"]

答案 3 :(得分:1)

谢谢(@ Doorknob,@ hirolau,@ Stefan,@ Cary Swoveland),您的所有回复都会在下面找到基准报告。

更新(星期二 - 2015年3月)

   require 'benchmark/ips'
    Benchmark.ips do |x|
      str = "TAMILNADU"
      x.report("1")  {
        pairs=[]
        numPairs= str.length()-1
        i=0
        while i<numPairs do
          pairs[i] = str.slice(i,2)
          i+=1
        end
      }
      x.report("2") {
        str.chars.each_cons(2).map(&:join)
      }
      x.report("3") {
        (0...str.size-1).map{|x| str[x,2]}
      }
      x.report("4"){
        str.scan(/(.)(?=(.))/).map(&:join)
      }
      x.report("5"){
        str.gsub(/(.)/,'\1\1')[1...-1].scan(/../)
      }
      x.report("6"){
        str.gsub(/./) { |c| c*2 }[1...-1].scan(/../)
      }
      x.compare!
    end
Calculating -------------------------------------
                   1    37.355k i/100ms
                   2     9.703k i/100ms
                   3    26.961k i/100ms
                   4     7.950k i/100ms
                   5     6.302k i/100ms
                   6     7.804k i/100ms
-------------------------------------------------
                   1    508.411k (±11.1%) i/s -      2.503M
                   2    107.568k (± 5.1%) i/s -    543.368k
                   3    332.923k (±10.2%) i/s -      1.672M
                   4     88.410k (± 4.5%) i/s -    445.200k
                   5     67.694k (± 4.8%) i/s -    340.308k
                   6     85.000k (± 5.8%) i/s -    429.220k

Comparison:
                   1:   508410.6 i/s
                   3:   332923.4 i/s - 1.53x slower
                   2:   107567.7 i/s - 4.73x slower
                   4:    88409.9 i/s - 5.75x slower
                   6:    85000.2 i/s - 5.98x slower
                   5:    67694.2 i/s - 7.51x slower

答案 4 :(得分:0)

使用正则表达式的另一种方式:

str.gsub(/(.)/,'\1\1')[1...-1].scan(/../)
  #=> ["TA", "AM", "MI", "IL", "LN", "NA", "AD", "DU"] 

或变体:

str.gsub(/./) { |c| c*2 }[1...-1].scan(/../)

任何其他人:

a = []
e = str.each_char
loop do
  a << (e.next << e.peek)
end
a

编辑:我在基准测试完成后添加了最后一个方法,所以我自己运行了基准测试。它已经死了。 (无论如何我喜欢它。)