gpt4 book ai didi

ruby - 有人可以解释为什么这个 Ruby next if 在 until 循环中工作吗?

转载 作者:数据小太阳 更新时间:2023-10-29 08:43:00 29 4
gpt4 key购买 nike

def sorting(arr)
sorted = false
until sorted
sorted = true
arr.each_index do |i|
next if i == arr.length - 1
if arr[i] > arr[i + 1]
arr[i], arr[i+1] = arr[i+1], arr[i]
sorted = false
end
end
end
arr
end

p sorting([7, 4, 5, 2, 1, 3]) => [1, 2, 3, 4, 5, 7]

我的问题是:为什么上面的 Ruby 代码可以工作?

首先:当我们在 until 循环中调用 sorted = true 时,它满足了 sorted 的条件,它应该结束循环。

第二:有人能解释一下为什么迭代方法里面的next if的过程不会继续迭代整个数组,当它应该在第一次迭代后结束时,然后调用 sorted = true

我被要求解释,我想知道是否有人可以提供更好的解释。

谢谢 Ruby 大师们!

最佳答案

首先,until是一个顶级测试循环。整个 block 必须在 until 之前循环再次测试条件;它不会在循环中的每个语句之后进行测试。你必须达到 endnextuntil 之前将再次评估。

第二,<statement> if <condition>if <condition> <statement> end 的 ruby 简写.它允许您在不牺牲可读性的情况下在一行中编写一个简单的条件。 next只会在 arr.each_index 的最后一次迭代时执行循环,向上堆栈到 until条件,到什么时候sorted将被设置为 false .

要查看其工作原理,请尝试运行以下修改:

#!/usr/bin/ruby

def sorting(arr)
puts "starting with #{arr}"
sorted = false
until sorted
sorted = true
arr.each_index do |i|
if i == arr.length - 1
puts "'next' when i == #{i}, arr = #{arr}"
next
end
if arr[i] > arr[i + 1]
puts "swapping at #{i}: #{arr[i]} <=> #{arr[i+1]}"
arr[i], arr[i+1] = arr[i+1], arr[i]
sorted = false
end
end
end
arr
end

p sorting([7,4,5,1,2,3])

这个程序的输出是:

starting with [7, 4, 5, 1, 2, 3]
swapping at 0: 7 <=> 4
swapping at 1: 7 <=> 5
swapping at 2: 7 <=> 1
swapping at 3: 7 <=> 2
swapping at 4: 7 <=> 3
'next' when i == 5, arr = [4, 5, 1, 2, 3, 7]
swapping at 1: 5 <=> 1
swapping at 2: 5 <=> 2
swapping at 3: 5 <=> 3
'next' when i == 5, arr = [4, 1, 2, 3, 5, 7]
swapping at 0: 4 <=> 1
swapping at 1: 4 <=> 2
swapping at 2: 4 <=> 3
'next' when i == 5, arr = [1, 2, 3, 4, 5, 7]
'next' when i == 5, arr = [1, 2, 3, 4, 5, 7]
[1, 2, 3, 4, 5, 7]

这当然是学术性的:对数组进行排序的正确方法是使用 Array#sort .

注:next完全是必要的,因为在 each_index 的最后一次迭代中循环,i + 1将超出数组的范围,这将导致下一行访问 arr[i + 1]失败(它将评估为 nil ,并且您不能将 Integer 与 nil 进行比较)。这样做的替代方法是修改围绕测试索引的交换的条件,或者将枚举数组的循环外部更改为更小的范围。

修改条件,消除next ,这是有效的,因为逻辑与条件是从左到右评估的,并且解释器在第一个为假时立即停止:

def sorting(arr)
sorted = false
until sorted
sorted = true
arr.each_index do |i|
if (i < arr.size - 1) && (arr[i] > arr[i + 1])
arr[i], arr[i+1] = arr[i+1], arr[i]
sorted = false
end
end
end
arr
end

p sorting([7,4,5,1,2,3])

改变循环的范围,更好的是循环执行的次数更少:

def sorting(arr)
sorted = false
until sorted
sorted = true
(0..arr.size - 2).each do |i|
if (arr[i] > arr[i + 1])
arr[i], arr[i+1] = arr[i+1], arr[i]
sorted = false
end
end
end
arr
end

p sorting([7,4,5,1,2,3])

next类似于 goto使用其他语言,应尽可能避免使用。

关于ruby - 有人可以解释为什么这个 Ruby next if 在 until 循环中工作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46984090/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com