繁体   English   中英

Ruby 中的操作顺序是什么?

[英]What is the order of operations in Ruby?

这是应用学院准备问题中的一个问题 - 有人可以解释答案。 我不明白这个 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,所以所有的奇数在两边都有一个破折号,除了最后的情况。

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

谢谢!

在 while 块的第一次迭代中,此条件不成立

if i > 0 

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

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

i = 0 num_s = "32467743"

在while循环内。

  • digit = 3 , i = 0if i > 0 is false ,那么dashed = "3"
  • digit = 2 , i = 1 , prev_digit = 3 , if i > 0 is true , if prev_digit%2 == 1 || digit%2 == 1 is true if prev_digit%2 == 1 || digit%2 == 1 is true ,所以dashed = "3-"if i > 0块,则代码退出,然后 dashed 正在更新dashed = 3-2

一切正常。

这里有一些用于教育目的的替代解决方案。 这个用odd? flat_map来编译字符部分的数组,然后将它们压缩在一起并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

添加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

dashed += num_s[i] ## 为什么首先添加到“DASHED”?

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

虚线 += "-" ## 此行第一

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

dashed + num=3

只有在第二次迭代中 i = 1,所以if i > 0变为真并允许执行dashed += "-"

dashed in if=3-

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM