循环基本上分两种:
在 Julia 中这两种都可行,不过第二种可能更常见。
while循环对于循环次数事先未知的开放式问题,Julia 提供了while循环。
基本形式相当简单:
while condition
do_something()
end
在这种情况下,程序会不断循环,直到condition不再是true。
有两种提前退出循环的方式:
break会让循环退出,程序从循环end之后的那一行继续执行。return x会停止当前函数的执行,并把返回值x传回给调用方。有了这些手段,有时可以先创建一个“无限”循环while true ... end,再依靠在循环体内部找到停止条件来触发break或return,这样会很方便。
最简单的例子是遍历一个范围。
如果我们想把某件事做 10 次:
for n in 1:10
do_something(n)
end
如果当前迭代不满足某个条件,可以用continue立即跳到下一次迭代:
for n in 1:10
if is_useless(n)
continue
end
# we decided this iteration could be useful
do_something_slow(n)
end
更简短的形式是,把if块替换成is_useless(n) && continue。
还可以遍历许多其他集合类型:数组中的元素、字符串中的字符、字典中的键……
到目前为止的例子都在遍历范围1:10,其中的值同时也是循环下标。
更一般地说,需要的可能不只是值,还有下标。
为此可以使用eachindex()函数,例如for i in eachindex(my_array) ... end。
你的朋友 Li Mei 经营着一家果汁吧,店里卖好喝的混合果汁。 你是她店里的常客,你发现可以让朋友的工作轻松一些。 你决定用自己的编程技能帮 Li Mei 分担一些活儿。
Li Mei 喜欢提前告诉顾客,他们点的菜单上的果汁需要等多久。
她很难记住确切的数字,因为调制不同果汁所需的时间各不相同。
"Pure Strawberry Joy" 需要 0.5 分钟,"Energizer" 和 "Green Garden" 各需要 1.5 分钟,"Tropical Island" 需要 3 分钟,"All or Nothing" 需要 5 分钟。
其他所有饮品(例如特惠款)可以按 2.5 分钟的调制时间计算。
为了帮你的朋友,请编写一个函数 time_to_mix_juice,它接收菜单上的一种果汁作为实参,并返回调制这种饮品所需的分钟数。
julia> time_to_mix_juice("Tropical Island")
3
julia> time_to_mix_juice("Berries & Lime")
2.5
Li Mei 的很多作品都会用到青柠角,有时作为原料,有时用于装饰。 所以早上开始上班时,她要确保装青柠角的盒子是满的,够一整天用。
实现函数 limes_to_cut,它接收 Li Mei 需要切的青柠角数量,以及一个数组,表示她手头现有的完整青柠。
一个 "small" 青柠可以切出 6 个青柠角,一个 "medium" 青柠可以切出 8 个,一个 "large" 青柠可以切出 10 个。
她总是按照青柠在列表中出现的顺序来切,从第一项开始。
她一直切到凑够所需的青柠角数量,或者用完所有青柠为止。
Li Mei 想提前知道她需要切多少个青柠。
limes_to_cut 函数应该返回需要切的青柠个数。
julia> limes_to_cut(25, ["small", "small", "large", "medium", "small"])
4
Li Mei 喜欢记录调制顾客正在等待的订单需要多长时间。
实现 order_times 函数,它接收一个订单队列,并返回一个调制时间向量。
julia> order_times(["Energizer", "Tropical Island"])
[1.5, 3.0]
Li Mei 总是工作到下午 3 点。 然后她的员工 Dmitry 来接替她。 Li Mei 下班时,经常还有一些饮品已经点单但还没做好。 剩下的果汁就由 Dmitry 来调制。
为了让交接更轻松,请实现一个函数 remaining_orders,它接收 Li Mei 本轮班剩余的分钟数,以及一个数组,里面是已经点单但还没调制的果汁。
该函数应返回 Li Mei 在下班前来不及开始调制的订单。
本轮班剩余的时间总是大于 0。 待调制的果汁数组不会为空。 此外,订单按照它们在数组中出现的顺序调制。 只要 Li Mei 开始调制某杯果汁,她就一定会做完,哪怕要多加一会儿班。 如果没有任何需要 Dmitry 处理的剩余订单,则应返回一个空向量。
julia> remaining_orders(5, ["Energizer", "All or Nothing", "Green Garden"])
["Green Garden"]