3

How do I append two lists together, and delete duplicates?

For example:

(setq list1 ("a" "b" "c"))
(setq list2 ("b" "c" "d"))

(setq list3 (a b c))
(setq list4 (c d e))

;; use case
(append-list-to-list list1 list2) ; ("a" "b" "c" "d")
(append-list-to-list list3 list4) ; (a b c d e)

UPDATE after the cl-union answer: I need to preserve the order of the resulting list.

And when there is a nested list, how do I append and make element is unique in list.

For example:

(a (b c) d) or ((a b) c d) etc
add list (x y z) to list ((a b) c d) to become ((a b x y z) c d)

Then how to append a new list to upper nested list?

2 Answers 2

1

I think you meant your first case to result in '(a b c d) but correct me if I'm wrong.

It seems like you're looking for the logical union, this is available as cl-union or if you want to use the dash.el library you can use their provided -union.

(cl-union '(a b c) '(b c d)) -> '(a b c d)

4
  • Common Lisp union makes no guarantees about the order: "The order of elements in the result do not have to reflect the ordering of list-1 or list-2 in any way." -- Common Lisp Hyperspec. The OP does not specify the requirements clearly, but the examples seem to preserve order, and the word append is used, which strongly suggests order preservation. (And yes, presumably the list1 + list2 examples shows the wrong result.)
    – Drew
    Feb 21, 2016 at 6:23
  • What if I have a nested list2 in list1, then how to do? Feb 21, 2016 at 6:45
  • 1
    It depends on the behavior you're looking for. A union would keep the nested lists. Perhaps you want to do something like flattening first? If so, again dash.el#flatten can help. Feb 21, 2016 at 6:48
  • There are more questions that need to be answered: what to do when the original lists contained duplicates? What equality function should be used to establish that two elements are equal. If elements are found to be equal, which one should be used?
    – wvxvw
    Feb 21, 2016 at 11:21
8

append does what the first part of your question asks:

(append &rest SEQUENCES)

Concatenate all the arguments and make the result a list. The result is a list whose elements are the elements of all the arguments. Each argument may be a list, vector or string. The last argument is not copied, just used as the tail of the new list.

delete-dups does what the second part of your question asks:

(delete-dups LIST)

Destructively remove equal duplicates from LIST. Store the result in LIST and return it. LIST must be a proper list. Of several equal occurrences of an element in LIST, the first one is kept.

(setq temp1 '(a b c))
(setq temp2 '(c d e))

(append temp1 temp2)                ; => (a b c c d e)
(delete-dups (append temp1 temp2))  ; => (a b c d e)

There are also Common Lisp options in the cl-lib library, if you're interested.

I did not understand what you meant in your question update about nested lists. Let me suggest you remove the nested lists from this question and post it as a separate question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.