Still working on lisp recipes and idioms.
I have a list like this:
((a b c) (d e f) nil (g h))
I'd like to consolidate that to one list,
(a b c d e f g h)
Seems like there oughta be a one-liner for th开发者_开发技巧at.
(apply #'append '((a b c) (d e f) (g h i)))
or
(loop for outer in '((a b c) (d e f) (g h i))
nconcing (loop for inner in outer collecting inner))
That's a typical homework question. Generally this operation is called FLATTEN (which flattens lists on all levels).
(mapcan #'copy-list '((a b c) (d e f) nil (g h)))
The APPLY variant has the problem that it may run into the CALL-ARGUMENTS-LIMIT when there are more sublists than CALL-ARGUMENTS-LIMIT.
See for example also http://rosettacode.org/wiki/Flatten_a_list#Common_Lisp
In the vein of the answer involving reduce
and append
, you can also use the :from-end
argument to reduce
, which is much more efficient as it avoids the unnecessary copying of the result in progress because append
doesn't copy its second argument:
(reduce #'append '((a b c) (d e f) nil (g h)) :from-end t)
You can also use reduce
and append
:
(reduce #'append '((a b c) (d e f) nil (g h)))
Unfortunately this is much less time and space efficient than the other solutions because it calls append
a lot and copies the result-in-progress unnecessarily.
精彩评论