【问题标题】:Sublist in common lispcommon lisp 中的子列表
【发布时间】:2015-03-31 04:47:06
【问题描述】:

我的程序中有列表列表 例如

 (( a b) (c d) (x y) (d u) ........)

实际上我想在列表中添加 1 个新元素,但新元素将是所有现有子列表的父元素。

例如如果一个新元素是z,那么我的列表应该变成这样

  ( (z( a b) (c d) (x y) (d u) ........))

我尝试过推送新元素,但它的列表是这样的

  ( z( a b) (c d) (x y) (d u) ........)

我不想要,因为我有很多新元素进来,每个元素代表列表中的一些子列表块

我们将非常感谢您的帮助。

【问题讨论】:

标签: lisp common-lisp


【解决方案1】:

听起来您只需要将 pushconslist* 的结果包装在另一个列表中:

(defun add-parent (children parent)
  (list (list* parent children)))

(add-parent '((a b) (c d) (x y) (d u)) 'z)
;;=> ((Z (A B) (C D) (X Y) (D U)))

这是我可能会采用的方法。保存返回值很重要。在这方面,它有点像 sort 函数。

但是,如果您想从中创建破坏性宏,您也可以使用 define-modify-macro 来实现。在下文中,我们使用define-modify-macro 定义一个宏add-parentf,它将其第一个参数更新为调用add-parent(如上定义)的结果第一个参数和父级。

(define-modify-macro add-parentf (parent) add-parent)

(let ((kids (copy-tree '((a b) (c d) (x y) (d u)))))
  (add-parentf kids 'z)
  kids)
;;=> ((Z (A B) (C D) (X Y) (D U)))

【讨论】:

    【解决方案2】:

    对于这种简单的情况,您还可以使用较短的反引号方法,例如:

    (let ((parent 'z) (children '((a b) (c d) (e f))))
        `((,parent ,@children)))
    

    如果您不熟悉反引号,我建议您阅读附录 D:阅读 Paul Graham 的 ANSI Common Lisp 的宏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-16
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 2011-05-12
      • 2010-09-15
      相关资源
      最近更新 更多