【问题标题】:Iterate through a list and check each element with your own condition?遍历列表并根据自己的条件检查每个元素?
【发布时间】:2017-04-08 23:15:42
【问题描述】:

作为一项家庭作业,我正在尝试遍历列表并对我在 Common Lisp 中遇到的每个元素进行 if 语句。 我的大部分问题都来自于我对语法不太了解。

这是我想要做的:

*lst* 是例如(1 4 2 6 4 7 2 4)

(setq finalList())

(loop for x in lst                      

    (if ((< x 5) && (not(equal(x nil))))       ; IF x < 5 and x != nil

         (append lst x)                        ; THEN STATEMENT

         (princ "Skip")                        ; ELSE STATMENT
     )

逻辑上应该这样做,但是,我的语法可能有误 (如果这里忘记多出冒号,判断是否为伪代码,谢谢)

如何遍历列表并对遇到的每个元素进行 if else 语句?

【问题讨论】:

  • 请注意,您的问题是关于 Common Lisp 语言,而不是 CLISP 一个 Common Lisp 实现。
  • 使用loop,您走在了正确的道路上。然而它是一个macro 并且它有特殊的语法,因此你不能只在它的“body”中插入 s 表达式并期望它能够工作。有些人甚至会说loopformat 设施本身就是一种完整的语言。

标签: list loops if-statement syntax common-lisp


【解决方案1】:

错误

  1. 语法:你需要前缀and,而不是中缀&amp;&amp;

  2. loopif 表单之前需要关键字do

  3. append 是非破坏性的,因此如果您没有将其返回值分配给变量,那么您什么也不做。

  4. Lisp 函数调用语法是 (func arg1 arg2 ...),而不是您在 equal 调用中使用的 (func (arg1 arg2 ...))

  5. 条件的顺序很重要:如果xnil,那么(&lt; x 5) 将发出错误信号,因此您需要在比较之前检查x

  6. 又长又复杂的(not (equal x nil))实际上等价于x

  7. 与其他语言(例如 C 和 Python)不同,在 Lisp parens 中,foo(foo)((foo)) 是三个非常不同的东西,永远不能互换使用。

解决方案

使用 Loop 微语言

loop 工具非常完美,因为它具有 ifcollect 子句:

(loop for x in lst
   if (and x (< x 5))
   then collect x
   else (print x))

注意:这看起来并不像 Lisp,因此您可能希望在学习该语言时避免循环。

使用函数式编程

(remove-if-not (lambda (x) (and x (< x 5))) lst)

注意:这不会打印删除的元素,我相信您有 print 子句仅用于调试。

使用迭代

(let ((res ()))
  (dolist (x lst (nreverse res))
    (when (and x (< x 5))
      (push x res))))

注意:我使用nreverse:由于我们自己构建结果列表,所以没有理由不使用破坏性版本或reverse

【讨论】:

  • 先生,您刚刚解决了我从这项任务中遇到的所有问题!非常感谢!
猜你喜欢
  • 1970-01-01
  • 2022-08-14
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
  • 2017-08-21
  • 2013-04-08
  • 2018-03-14
  • 2015-10-03
相关资源
最近更新 更多