![](/img/trans.png)
[英]what is ruby-on-rails' order of operations when constructing from a hash?
[英]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 = 0
, if 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.