while/直到纳什尔循环
作者注:此问题使用过时的语法和旧版本Nushell的语句。请参阅下面的答案,以获取更新的语法。
您如何在nushell脚本中进行/直到循环?
由于Nushell具有相当惊人的表/JSON解析系统,因此我一直在尝试与 stack Exchange API 通过它。
第一个挑战之一是在多个可能的页面上进行循环。我的(通常是程序性的,有时是OOP)背景让我在Nushell中伸手去拿一个构造,例如:
let page = 1
let re = (http (echo "/2.3/questions?fromdate=1648771200&todate=1648944000&order=desc&sort=activity&site=askubuntu&page=" $page) | from json)
let questions = $re.items
while ($re.has_more) {
let page = page + 1
let re = (http (echo "/2.3/questions?fromdate=1648771200&todate=1648944000&order=desc&sort=activity&site=askubuntu&page=" $page) | from json)
let questions = $questions | append $re.items
}
...或等效,直到
构造为止。
我将如何在Nushell中实现这一目标?
注意 - 使用 httpie 在上面的示例中,因为它自动处理gzip
压缩该压缩堆栈API需要(不同于WGET
或Nushell的内部fetch
命令)。
Author's note: This question uses outdated syntax and statements from an older version of Nushell. Please see the answer(s) below for the updated syntax.
How do you do while/until loops in Nushell script?
Since Nushell has a fairly amazing table/JSON parsing system, I've been trying to work with the Stack Exchange API through it.
One of the first challenges is looping over the multiple possible pages of results from an API call. My (normally procedural, sometimes OOP) background had me reaching for a construct in Nushell like:
let page = 1
let re = (http (echo "/2.3/questions?fromdate=1648771200&todate=1648944000&order=desc&sort=activity&site=askubuntu&page=" $page) | from json)
let questions = $re.items
while ($re.has_more) {
let page = page + 1
let re = (http (echo "/2.3/questions?fromdate=1648771200&todate=1648944000&order=desc&sort=activity&site=askubuntu&page=" $page) | from json)
let questions = $questions | append $re.items
}
... or the equivalent until
construct.
How would I accomplish this in Nushell?
Note - Using httpie in the above example since it automagically handles the gzip
compression that the Stack API requires (unlike wget
or Nushell's internal fetch
command).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
简短答案:
在 Nushell 0.72 ,现在支持循环,以及可变变量以帮助处理此类循环。
直到
- 风格的循环也可以通过loop
/使用
使用break
语句。注意:我将根据当前可用的Nushell 0.84更新此答案,以更新最新的语法。请记住,Nushell在通往1.0的路径上继续演变其
。
语法 作品:
问题
在无限范围内收集httpie
来处理SE API的gzzpief结果,但现在,Nushell内置也可以正确处理此操作。$“ with($ variable_interprolation)”
更新页码$ res
将有效载荷(问题)保存在$ $ $中res.items),然后将其附加到Mutable
$问题清单上。$ res.has_more
告诉我们是否需要继续循环。如果不是,我们break
它。这是一个简单的,直到
条件为止。有了这个就位,您现在可以访问
$问题
根据需要将结果切下来:结果(在原始答案时):
是的,Nushell实际上很明显结果桌子。
当然,<代码> 循环也使用可变变量非常干净地支持。和一个通用
loop
/break
构造是,直到
对x in 1 .. 短手。需要一个增量变量。来自Nushell帮助:
while:
mut x = 0; $ x&lt; 10 {$ x = $ x + 1}
循环:
mut x = 0; loop {如果$ x&gt; 10 {break}; $ x = $ x + 1}; $ x
当然,实际上最好用的
提供。
较旧的信息:
但是,我原始的0.72答案(使用递归功能)仍然是处理此操作的有效方法(并且可能是有用的技术),但请记住,Nushell没有尾巴回归。
使用递归,Nushell中的基本“ while”循环看起来像:
相应的直到循环可能看起来像:
如果您需要修改变量,请记住它范围范围为块,因此您需要将其传递回递归函数。例如,要使用堆栈Exchange API并更新每个调用的页码:
请注意,每个未来的呼叫都是
Append
ed到当前结果。另请注意,返回结果必须是函数中执行的最后一个语句。
旁注:个人意见 - 我设想Nushell最终会添加
yount
关键字以允许发电机表达式。这将仅在降低
中允许它可以累积结果来进一步示例。Short answer:
As of Nushell 0.72,
while
loops are now supported, along with mutable variables to assist in the handling of such loops.until
-style loops can also be replicated throughloop
/for
with thebreak
statement.Note: I'm updating this answer to the latest syntax based on the currently available Nushell 0.84. Keep in mind that Nushell continues to evolve its syntax on its path to 1.0.
The example in the question can now be handled fairly easily (as concisely and cleanly as my original question's pseudo-code, at least) with:
This works by:
questions
to collect the results of each iterationfor
loops over an infinite range of1..
http get
to retrieve the next page. While in the original question I mentioned that I needed to usehttpie
to handle the SE API's gzipped results, the Nushell builtin now handles this properly as well.$"string with ($variable_interprolation)"
to update the page number$res
holds the payload (the questions) in$res.items), which is then appended to the mutable
$questions` list.$res.has_more
to tell us if we need to continue the loop. If not, webreak
it. This acts as a simpleuntil
condition.With that in place, you can now access
$questions
to slice-and-dice the results as needed:Result (at the time of the original answer):
And yes, Nushell actually pretty-prints the results table.
Of course,
while
loops are also supported quite cleanly using mutable variables. And a genericloop
/break
construct isuntil
short-hand forfor x in 1..
when you don't need an incrementing variable.From the Nushell help:
While:
mut x = 0; while $x < 10 { $x = $x + 1 }
Loop:
mut x = 0; loop { if $x > 10 { break }; $x = $x + 1 }; $x
Although in reality that would be better served with a
for
, of course.Older info:
However, my original, pre-0.72 answer, using recursive functions, is still a valid way of handling this (and may a useful technique), but do keep in mind that Nushell does not have tail-recursion.
Using recursion, a basic "while" loop in Nushell might look something like:
And a corresponding until-loop might look like:
If you need to modify a variable, keep in mind that it is scoped to its block, so you'll need to pass it back in to the recursive function. For instance, to work with the Stack Exchange API and update the page number for each call:
Note that each future call is
append
ed to the current results.Also note that the return results must be the last statement executed in the function.
Side-note: Personal opinion -- I envision that Nushell will eventually add a
yield
keyword to allow generator expressions. This will simply the above example further by allowing it inside areduce
that can accumulate the results.