JaT*_*aTo 7 ruby loops language-construct
我最近遇到了使用Loop Do的问题/解决方案.到目前为止,我在学习Ruby编程时很少见到这一点(我是一名没有CS经验的初学者).
# Write a function, `nearest_larger(arr, i)` which takes an array and an
# index. The function should return another index, `j`: this should
# satisfy:
#
# (a) `arr[i] < arr[j]`, AND
# (b) there is no `j2` closer to `i` than `j` where `arr[i] < arr[j]`.
#
# In case of ties (see example beow), choose the earliest (left-most)
# of the two indices. If no number in `arr` is largr than `arr[i]`,
# return `nil`.
#
# Difficulty: 2/5
describe "#nearest_larger" do
it "handles a simple case to the right" do
nearest_larger([2,3,4,8], 2).should == 3
end
it "handles a simple case to the left" do
nearest_larger([2,8,4,3], 2).should == 1
end
it "treats any two larger numbers like a tie" do
nearest_larger([2,6,4,8], 2).should == 1
end
it "should choose the left case in a tie" do
nearest_larger([2,6,4,6], 2).should == 1
end
it "handles a case with an answer > 1 distance to the left" do
nearest_larger([8,2,4,3], 2).should == 0
end
it "handles a case with an answer > 1 distance to the right" do
nearest_larger([2,4,3,8], 1).should == 3
end
it "should return nil if no larger number is found" do
nearest_larger( [2, 6, 4, 8], 3).should == nil
end
end
Run Code Online (Sandbox Code Playgroud)
解
def nearest_larger(arr, idx)
diff = 1
loop do
left = idx - diff
right = idx + diff
if (left >= 0) && (arr[left] > arr[idx])
return left
elsif (right < arr.length) && (arr[right] > arr[idx])
return right
elsif (left < 0) && (right >= arr.length)
return nil
end
diff += 1
end
end
nearest_larger([2,4,3,8], 1)
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释何时是使用"循环做"构造而不是通常的"while"或"除非"或"每个"构造的最佳时间?
rad*_*dyz 24
加上以前的答案,
在使用外部迭代器时,"loop do"构造还提供了更清晰的语法,例如
没有"循环做"
my_iterator = (1..9).each
begin
while(true)
puts my_iterator.next
end
rescue StopIteration => e
puts e
end
Run Code Online (Sandbox Code Playgroud)
而现在用"循环做"这将成为
my_iterator = (1..9).each
loop do
puts my_iterator.next
end
Run Code Online (Sandbox Code Playgroud)
并且处理异常.它还允许您同时循环遍历两个集合,只要其中一个集合耗尽,循环就会优雅地退出,
iterator = (1..9).each
iterator_two = (1..5).each
loop do
puts iterator.next
puts iterator_two.next
end
Run Code Online (Sandbox Code Playgroud)
它将打印:1,1,2,2,3,3,4,4,5,5,6.
更多信息:ruby-docs.org
Nei*_*ter 12
在没有的语言中loop,您可以使用如下while构造:
while( true ) {
# Do stuff until you detect it is done
if (done) break;
}
Run Code Online (Sandbox Code Playgroud)
关键是你在不知道要执行多少次迭代的情况下启动循环(或者事先很难计算),但是很容易检测循环何时结束.此外,对于特定情况,您可能会发现等效while (! done) { # do stuff }语法笨拙,因为完成条件可能发生在循环的中途,或者在多个位置.
Ruby loop与基本相同while( true )- 事实上你while( true )几乎可以互换使用它.
在给定的示例中,每次迭代中都有以下返回点:
if (left >= 0) && (arr[left] > arr[idx])
return left # <-- HERE
elsif (right < arr.length) && (arr[right] > arr[idx])
return right # <-- HERE
elsif (left < 0) && (right >= arr.length)
return nil # <-- HERE
end
Run Code Online (Sandbox Code Playgroud)
如果没有满足结束条件,这里还有一个暗示的"其他继续循环".
这些多个可能的出口点可能是作者选择loop构造的原因,尽管在实践中使用Ruby有很多方法可以解决这个问题.给定的解决方案代码不一定优于所有其他可能性.