【问题标题】:Lisp: Collect multiple lists in loopLisp:循环收集多个列表
【发布时间】:2017-05-12 23:22:14
【问题描述】:

我希望能够在一个循环中收集多个列表。

我知道这可以在没有循环的情况下完成,但是我想知道这是否也可以通过循环来实现。我想要这样的东西:

  (loop for var in list
        (if (cond1 var)
            (if (cond2 var)
                collect into list1
                collect into list2))
        finally (list list1 list2))

我收到LOOP keyword is expected 的错误,我猜应该在whenloop 之后立即使用collect。有什么办法可以解决吗?

【问题讨论】:

    标签: loops lisp common-lisp


    【解决方案1】:

    信不信由你括号太多loop 有自己的小子语言,与 Common Lisp s 表达式完全不同。

    (loop :for var :in list
          :when (cond1 var)
            :if (cond2 var)
               :collect var :into list1
            :else
               :collect var :into list2
            :end
          :end
          :finally (return (list list1 list2)))
    

    此外,我还指定了 :collect:finally 仅评估的内容,因此您需要使用 (return ...) 否则您可以期待 nil

    我对@9​​87654333@ 关键字使用关键字来将它们与其他符号区分开来。这只是风格。缩进当然会被忽略,只是为了便于阅读,但:end 不是。但是在这种情况下,:end 两个关键字都是多余的,因为在没有它们的情况下 loop 可以正确解析。

    我绝不是loop 奇才。每次我遇到一些稍微复杂的事情时,我倾向于使用Land of Lisp 的周期表或Loop for black belts,来自Practical Common Lisp 的章节。

    【讨论】:

    • 能分享一下“循环宏周期表”的出处吗?
    • @Hellseher 正如我在回答中所写的,它来自Land of Lisp 这本书。互联网上有一个 PDF 版本,但是由于这是受版权保护的作品,我认为在 SO 上放上它不会被视为合理使用。我拥有一本,并敦促所有有兴趣购买这本书的人,因为它是一件很棒的艺术品。
    【解决方案2】:

    你有几个问题。

    首先,如果你想把普通的 Lisp 代码放入循环体中,你需要 do 关键字。但是您可以使用dowhenif 关键字代替。

    其次,collect 关键字要求您指定要收集到列表中的表达式,例如collect var into list1.

    第三,您需要使用(return expression)finally子句中的表单返回一个值。

      (loop for var in list
        when (cond1 var)
          if (cond2 var)
            collect var into list1
          else
            collect var into list2
        finally (return (list list1 list2)))
    

    【讨论】:

    • 两个答案都很好,但这是我让它全部运行所需要的!谢谢
    猜你喜欢
    • 2013-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 2018-04-24
    相关资源
    最近更新 更多