Ruby中的操作顺序是什么?

时间:2017-10-20 21:09:14

标签: ruby-on-rails ruby logic

这是来自app学院准备问题的问题 - 有人可以解释答案。我不明白操作顺序在这个while循环中是如何工作的:

def dasherize_number(num)
  i = 0 
  dashed = ""
  num_s = num.to_s 

  while i < num_s.length
    digit = num_s[i].to_i
    if i > 0 
      prev_digit = num_s[i-1].to_i
      if prev_digit%2 == 1 || digit%2 == 1 
        dashed += "-" ## THIS LINE COMES FIRST

      end 
    end

    dashed += num_s[i] ## WHY IS THIS ADDED TO "DASHED" FIRST?

    i += 1
  end 
  return dashed
end

puts(dasherize_number(32467743))

结果是3-245-7-7-4-3,所以除了最终案例之外,所有奇数都在两边都有破折号。

对我来说,插入破折号的命令会添加到原始字母后的新字符串中,即使它在代码中排在第一位也没有意义。

谢谢!

4 个答案:

答案 0 :(得分:0)

在while块的第一次迭代中,这个条件不正确

if i > 0 

然后数字被添加到dashed并且从下一次迭代开始,即使条件为真,这两件事可能会让你感到困惑

答案 1 :(得分:0)

让我们跟踪while代码的前两次迭代。

i = 0 num_s = "32467743"

在while循环中。

  • digit = 3i = 0if i > 0 is false,SO dashed = "3"
  • digit = 2i = 1prev_digit = 3if i > 0 is trueif prev_digit%2 == 1 || digit%2 == 1 is true,SO dashed = "3-",然后代码退出if i > 0块,然后破折号正在更新dashed = 3-2

一切正常,井然有序。

答案 2 :(得分:0)

以下是一些用于教育目的的替代解决方案。这个使用odd?flat_map来编译一个字符部分数组,然后将它们压缩在一起并去掉不需要的箔条:

def dasherize_number(num)
  num.to_s.chars.map(&:to_i).flat_map do |d|
    if (d.odd?)
      [ '-', d, '-' ]
    else
      d
    end
  end.join('').gsub(/\-\-+/, '-').sub(/\A\-/, '').sub(/\-\z/, '')
end

这是一个在正则表达式级别上工作的方法,通过在一行中应用多个替换来获得最终结果:

def dasherize_number(num)
  {
    /([13579])/ => '-\1-',
    /\-\-+/ => '-',
    /\A\-/ =>  '',
    /\-\z/ => ''
  }.inject(num.to_s) do |n, (rx, sub)|
    n.gsub(rx,sub)
  end
end

答案 3 :(得分:0)

添加puts以跟踪发生的情况:

def dasherize_number(num)
  i = 0 
  dashed = ""
  num_s = num.to_s 
  puts "number=#{num_s}"

  while i < num_s.length
    digit = num_s[i].to_i
    if i > 0 
      prev_digit = num_s[i-1].to_i
      puts "prev_digit=#{prev_digit}   digit=#{digit}"

      if prev_digit%2 == 1 || digit%2 == 1 
        dashed += "-" ## THIS LINE COMES FIRST
        puts "dashed in if=#{dashed}"
      end 
    end

    dashed += num_s[i] ## WHY IS THIS ADDED TO "DASHED" FIRST?
    puts "dashed + num=#{dashed}"

    i += 1
  end 
  return dashed
end

puts(dasherize_number(32467743))

执行:

$ ruby -w t.rb 
number=32467743
dashed + num=3
prev_digit=3   digit=2
dashed in if=3-
dashed + num=3-2
prev_digit=2   digit=4
dashed + num=3-24
prev_digit=4   digit=6
dashed + num=3-246
prev_digit=6   digit=7
dashed in if=3-246-
dashed + num=3-246-7
prev_digit=7   digit=7
dashed in if=3-246-7-
dashed + num=3-246-7-7
prev_digit=7   digit=4
dashed in if=3-246-7-7-
dashed + num=3-246-7-7-4
prev_digit=4   digit=3
dashed in if=3-246-7-7-4-
dashed + num=3-246-7-7-4-3
3-246-7-7-4-3
  

虚线+ = num_s [i] ##为什么添加到&#34; DASHED&#34;第一λ

循环以i = 0开始,因此if i > 0不会被执行。

  

虚线+ =&#34; - &#34; ##此行首先出现

是的,首先在行中,但不在执行中,正是因为它位于then块中,取决于if i > 0,这在第一次迭代期间未执行,允许dashed += num_s[i]添加第一个数字为空dashed字符串。

dashed + num=3

仅在第二次迭代中i = 1,因此if i > 0变为真,并允许执行dashed += "-"

dashed in if=3-