内置Emacs Lisp库中此函数的名称?

时间:2009-06-09 09:28:43

标签: emacs lisp elisp

以下Emacs Lisp函数获取列表列表并返回一个列表,其中内部列表的项目已连接到一个大列表。这很简单,我确信这样的东西必须已经成为标准函数库的一部分。

(defun flatten (LIST)
  (if LIST
      (append (car LIST) (flatten (cdr LIST)))
    nil))

我正在寻找一个函数,它将单个列表列表作为其参数,然后附加所有内部列表。

(flatten '((a b) (c d)))

将给出

(a b c d)

有没有人知道这个功能是否已经内置,如果是,是以哪个名称?

谢谢!

6 个答案:

答案 0 :(得分:11)

你要么想要追加:

(defun flatten (list-of-lists)
  (apply #'append list-of-lists))

如果(并且仅当)您知道您将始终拥有列表列表。

否则:

(defun flatten (list)
  (mapcan (lambda (x) (if (listp x) x nil)) list))

答案 1 :(得分:7)

我最近才进入这里寻找不同的东西;根据原始问题是否意在引用通用列表(即:列表清单列表......)或者用于检查功能的测试数据,可能没有提供证据。只是两级列表(如示例所示)。

solution based on append仅适用于两级列表,solution based on mapcan还有一个问题。

基本上,一般解决方案必须在car和cdr上递归,如下面的flatten defun。

(setq l '((((1 2) 3) 4) (5 6 7)))

(defun flatten(x)
  (cond ((null x) nil)
    ((listp x) (append (flatten (car x)) (flatten (cdr x))))
    (t (list x))))

(defun flatten2(l)
  (if l (append (car l) (flatten2 (cdr l))) nil))

(defun flatten3(l)
  (mapcan (lambda(x) (if (listp x) x nil)) l))

(flatten l)
(1 2 3 4 5 6 7)

(apply #'append l)
(((1 2) 3) 4 5 6 7)

(flatten2 l)
(((1 2) 3) 4 5 6 7)

进一步的问题是在mapcan中使用flatten3:由于mapcan隐藏了nconc,用户必须记住更改其参数

l
((((1 2) 3) 4) (5 6 7))

(flatten3 l)
(((1 2) 3) 4 5 6 7)

l
((((1 2) 3) 4 5 6 7) (5 6 7))

答案 2 :(得分:5)

Dash是Emacs的现代列表库,并已展平。在magit之后,它是Melpa上下载次数最多的第二个包。来自readme

-flatten (l):采用嵌套列表l并将其内容作为单个平面列表返回。

(-flatten '((1))) ;; => '(1)
(-flatten '((1 (2 3) (((4 (5))))))) ;; => '(1 2 3 4 5)
(-flatten '(1 2 (3 . 4))) ;; => '(1 2 (3 . 4))

-flatten-n (num list):展平嵌套列表的num级别。

(-flatten-n 1 '((1 2) ((3 4) ((5 6))))) ;; => '(1 2 (3 4) ((5 6)))
(-flatten-n 2 '((1 2) ((3 4) ((5 6))))) ;; => '(1 2 3 4 (5 6))
(-flatten-n 3 '((1 2) ((3 4) ((5 6))))) ;; => '(1 2 3 4 5 6)

此套餐于2012-09开始。

答案 3 :(得分:2)

我意识到原来的问题是“什么是内置功能”。似乎没有。其他解决方案实际上并没有压缩我测试的所有列表。此功能似乎有效。我在这里发帖是因为这是Google在我搜索时首先点击的地方。

(defun flatten (LIST)
  "flattens LIST"
  (cond
   ((atom LIST) (list LIST))
   ((null (cdr LIST)) (flatten (car LIST)))
   (t (append (flatten (car LIST)) (flatten (cdr LIST))))))

e.g。

(flatten (list "a" (list "b" "c" nil) (list (list "d" "e") "f")))
("a" "b" "c" nil "d" "e" "f")

答案 4 :(得分:1)

查看nconc

答案 5 :(得分:1)

Emacs 27.1具有flatten-tree

(flatten '((a b) (c d)))

(a b c d)

请参阅:https://www.gnu.org/software/emacs/manual/html_node/elisp/Building-Lists.html