【问题标题】:Collect AND do something under a condition inside a Common Lisp loop在 Common Lisp 循环内的某个条件下收集并做某事
【发布时间】:2018-04-24 20:59:35
【问题描述】:

除了“收集”之外,我还需要在循环中的某个条件下执行一条指令,但我无法找出有效的语法...

例如,我希望下面的代码打印 i 并在 2

(loop for i '(1 2 3 4) in  when (< 2 i) (print i) collect i)  ==> (3 4)

希望你能帮忙!

【问题讨论】:

  • 2 美分:您可能会喜欢shinmera's For,它简单且一致。
  • 请务必遵循@Sylvester 的链接到 Seibels 的 LOOP 章节;时髦的语法不是人们可以猜测甚至在多次使用后记住的东西(我喜欢 LOOP)。

标签: loops lisp common-lisp


【解决方案1】:

:if:when 中的多个子句需要由:and 连接。关键字:end实际上被忽略了,除了让你读起来更放心。

(loop :for i :in '(1 2 3 4)
      :when (< 2 i) 
        :do (print i) 
        :and :collect i
      :end)  ; ==> (3 4) (and prints 3 and 4 as side effect)

我建议你阅读LOOP for Black Belts。如果您查看right above this part,您会在一个稍微复杂的示例中看到:and

注意:loop 接受来自任何包的符号,所以我的风格是使用关键字包,不要用loop 关键字污染我自己的包,我的编辑器会稍微更好地突出显示它。你不需要按照我的方式做:-)

【讨论】:

  • 关键字 END 是 LOOP 语法的一部分。
  • 循环关键字通过名称识别。因此,即使是一个没有嵌入到包中的符号也可以工作。
  • @RainerJoswig 是的,否则:end 不会被允许放在我放的地方。也许使用符号包的一个坏事是如果两个子句的顺序相反,则会评估像:endd 这样的错字。
  • 参见无条件。我们得到这个:{do |做}复合形式+。然后词汇表说:复合形式 n。一个非空列表,它是一种形式:特殊形式、lambda 形式、宏形式或函数形式。 这是 LOOP 语法的一个棘手部分。
  • @RainerJoswig 这是有道理的,因为:do 仅用于副作用并且评估变量没有副作用。我已经提交了错误报告。谢谢。
【解决方案2】:
CL-USER 71 > (loop for i in '(1 2 3 4)
                   when (> i 2)
                     do (print i) and collect i)

3        ; printed
4        ; printed
(3 4)    ; return value

【讨论】:

    【解决方案3】:

    在您的情况下,使用 print 的返回值会更短:

    (loop for i in '(1 2 3 4) when (> i 2) collect (print i))
    

    【讨论】:

    • 这不是我真正需要做的,这只是一个更简单的例子。实际代码中没有print
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 2018-11-14
    • 2014-07-24
    相关资源
    最近更新 更多