Author Topic: How to merge lists more effectively based on the same elements?  (Read 1799 times)

0 Members and 1 Guest are viewing this topic.

fools

  • Newt
  • Posts: 72
  • China
How to merge lists more effectively based on the same elements?
« on: December 04, 2017, 09:45:07 AM »
Input list:
(setq lst1 '(("1D61" "1D62")
       ("1D61" "1D62")
       ("1D63" "1D64" "1DB6")
       ("1D63" "1D64" "1D65")
       ("1D64" "1D65" "1D66")
       ("1D65" "1D66" "1D67")
       ("1D66" "1D67" "1D68")
       ("1D67" "1D68" "1DBE")
       ("1D7F" "1D80")
       ("1D7F" "1D80")
       ("1D81" "1D82" "1D83")
       ("1D81" "1D82" "1D83" "1D85")
       ("1D81" "1D82" "1D83")
       ("1D84" "1D85" "1D86")
       ("1D82" "1D84" "1D85" "1D86")
       ("1D84" "1D85" "1D86")
       ("1D63" "1DB6" "1DBF")
       ("1D68" "1DBE")
       ("1DB6" "1DBF")
      )
)

Each of the sublists in the output list has different elements.
Output list:
(setq lst2 '(("1D61" "1D62")
        ("1D63" "1D64" "1D65" "1D66" "1D67" "1D68" "1DB6" "1DBE" "1DBF")
        ("1D7F" "1D80")
        ("1D81" "1D82" "1D83" "1D84" "1D85" "1D86")
       )
)

It's my way, but it's too tedious.I hope to improve the combined efficiency.
All suggestions and opinions are welcome. Thanks.
Code - Auto/Visual Lisp: [Select]
  1. (defun foo (lst / item more out same tmp)
  2.   (while lst
  3.     (setq item (car lst)
  4.           more t
  5.     )
  6.     (while more
  7.       (setq tmp nil)
  8.       (foreach id item
  9.         (if (setq same (vl-remove-if-not '(lambda (x) (member id x)) lst))
  10.           (setq lst  (vl-remove-if '(lambda (x) (member id x)) lst)            
  11.                 tmp (append (cons item same) tmp)
  12.           )
  13.         )
  14.       )
  15.       (if tmp
  16.         (setq item (merge (apply 'append tmp)))
  17.         (setq more nil)
  18.       )
  19.     )
  20.     (setq out (cons item out))
  21.   )
  22.   out
  23. )
  24.  
  25. (defun merge (lst / tmp)
  26.   (foreach item (acad_strlsort lst)
  27.     (if (not (and tmp (equal (car tmp) item)))
  28.       (setq tmp (cons item tmp))
  29.     )
  30.   )
  31.   (reverse tmp)
  32. )
Good good study , day day up . Sorry about my Chinglish .

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: How to merge lists more effectively based on the same elements?
« Reply #1 on: December 04, 2017, 02:09:29 PM »
How about:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( lst / rtn tmp )
  2.     (foreach itm lst
  3.         (if (vl-some '(lambda ( x ) (setq tmp (vl-some '(lambda ( y ) (if (member x y) y)) rtn))) itm)
  4.             (setq rtn (subst (append tmp (vl-remove-if '(lambda ( x ) (member x tmp)) itm)) tmp rtn))
  5.             (setq rtn (cons itm rtn))
  6.         )
  7.     )
  8.     (reverse rtn)
  9. )

fools

  • Newt
  • Posts: 72
  • China
Re: How to merge lists more effectively based on the same elements?
« Reply #2 on: December 04, 2017, 08:53:21 PM »
How about:

Lee, thank you very much. Whenever I meet a problem, I can always get your help.
When the amount of data is large, your program is so many times faster than mine.
Good good study , day day up . Sorry about my Chinglish .

fools

  • Newt
  • Posts: 72
  • China
Re: How to merge lists more effectively based on the same elements?
« Reply #3 on: December 05, 2017, 09:29:46 AM »
How about:
Code - Auto/Visual Lisp: [Select]
  1. (defun foo ( lst / rtn tmp )
  2.     (foreach itm lst
  3.         (if (vl-some '(lambda ( x ) (setq tmp (vl-some '(lambda ( y ) (if (member x y) y)) rtn))) itm)
  4.             (setq rtn (subst (append tmp (vl-remove-if '(lambda ( x ) (member x tmp)) itm)) tmp rtn))
  5.             (setq rtn (cons itm rtn))
  6.         )
  7.     )
  8.     (reverse rtn)
  9. )

A little bug.  :cry:
When two adjacent items are different and have some same items with the following, will return error result.
Like this:
(setq lst '(("1D22" "1DC7")   ("1D23" "1D24") ("1D24" "1DC7")))
(foo lst)  --> (("1D22" "1DC7") ("1D23" "1D24" "1DC7"))

The correct result is (("1D22" "1D23" "1D24" "1DC7"))
Good good study , day day up . Sorry about my Chinglish .

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: How to merge lists more effectively based on the same elements?
« Reply #4 on: December 05, 2017, 10:53:06 AM »
How about :

Code - Auto/Visual Lisp: [Select]
  1. (defun foogather ( lst / foo rtn )
  2.  
  3.     (defun foo ( lst / rtn tmp )
  4.         (foreach itm lst
  5.             (if (vl-some '(lambda ( x ) (setq tmp (vl-some '(lambda ( y ) (if (member x y) y)) rtn))) itm)
  6.                 (setq rtn (subst (append tmp (vl-remove-if '(lambda ( x ) (member x tmp)) itm)) tmp rtn))
  7.                 (setq rtn (cons itm rtn))
  8.             )
  9.         )
  10.         (reverse rtn)
  11.     )
  12.  
  13.     (setq rtn (foo lst))
  14.     (while (not (equal rtn (setq rtn (foo rtn)))))
  15.     rtn
  16. )
  17.  

Quote
Untested though...
« Last Edit: December 05, 2017, 11:14:36 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

fools

  • Newt
  • Posts: 72
  • China
Re: How to merge lists more effectively based on the same elements?
« Reply #5 on: December 06, 2017, 02:36:36 AM »
How about :

Thanks for reply.
This is really a way, but perhaps also have some optimized space.
Good good study , day day up . Sorry about my Chinglish .