常见的lisp中的子列表

时间:2015-03-31 04:47:06

标签: lisp common-lisp

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

 (( 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) ........)

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

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

听起来你只需将推送缺点列表* 的结果包装在另一个列表中:

(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)))

这是我可能采取的方法。保存返回值非常重要。在这方面,它有点像排序功能。

但是,如果你想制作一个破坏性的宏,你也可以使用 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)))

答案 1 :(得分:0)

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

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

如果您不熟悉反引用,我建议您阅读附录D:阅读Paul Graham的ANSI Common Lisp中的简洁描述。