MJLM Posted June 22, 2014 Share Posted June 22, 2014 I want to break a list in two sub lists like that: List: (a b c d e f g) And get L1 as (a b c d) and L2 as (e f g). It s easy to get the second L2 with (member e ls) and frankly i can get the L1 with a "foreach" and "cons" function but it seems to much of a code for that. Is there a function like "member" to get the L1 faster and with less code? A vl-something function maybe? Thank you Quote Link to comment Share on other sites More sharing options...
a_67vdub Posted June 22, 2014 Share Posted June 22, 2014 How about throwing a couple reverses in there? So getting L1 would be just like getting L2: (reverse (member d (reverse ls))) I'm definitely no lisp expert, so take my suggestions with a grain of salt. Quote Link to comment Share on other sites More sharing options...
ymg3 Posted June 22, 2014 Share Posted June 22, 2014 (edited) This function by Gile Chanteau: You supply n which is number of element in first list and l the list. defun breakAt (n l / r) (while (and l (< 0 n)) (setq r (cons (car l) r) l (cdr l) n (1- n) ) ) (list (reverse r) l) ) As an alternative you could use function trunc also by by Gile Chanteau You supply expr and the list. In your case expr woulld be e (defun trunc (expr lst) (if (and lst (not (equal (car lst) expr)) ) (cons (car lst) (trunc expr (cdr lst))) ) ) So your first list would be: (setq L1 (trunc e lst)) The second one: (setq L2 (member e lst) ) Edited June 22, 2014 by ymg3 Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted June 22, 2014 Share Posted June 22, 2014 Another: (defun breakatitem ( x l / r ) (setq l (vl-member-if '(lambda ( y ) (setq r (cons y r)) (equal x y)) l)) (list (reverse (cdr r)) l) ) _$ (breakatitem 'e '(a b c d e f g)) ((A B C D) (E F G)) _$ (breakatitem 'h '(a b c d e f g)) ((A B C D E F) nil) _$ (breakatitem 'a '(a b c d e f g)) (nil (A B C D E F G)) Quote Link to comment Share on other sites More sharing options...
hanhphuc Posted June 25, 2014 Share Posted June 25, 2014 (edited) @ymg & LM sorry mine is out of topic, this code just split equally. Just for sharing if others see this thread for similarity. split by division or length with opt T or nil (defun split (lst len opt / ls l i) ; opt, T= by division or nil=by length (setq i 1 l '() len (if opt (/ (length lst) len) len)) (while lst (setq l (append l (list(car lst)))) (if (zerop (rem i len)) (setq ls (cons l ls) l nil) ) (setq i (1+ i) lst (cdr lst)) ) ;_ end of foreach (if l (append (reverse ls) (list l)) (reverse ls) ) ;_ end of if ) ;_ end of defun Test: (setq a '(1 2 3 4 5 6 7 8 9 0)) ; split by division (split a 3 t) ;((1 2 3) (4 5 6) (7 8 9) (0)) (split a 2 t) ;((1 2 3 4 5) (6 7 8 9 0)) (split a 1 t) ;((1 2 3 4 5 6 7 8 9 0)) ; split by length (split a 3 nil) ;((1 2 3) (4 5 6) (7 8 9) (0)) (split a 2 nil) ;((1 2) (3 4) (5 6) (7 (9 0)) (split a 1 nil) ;((1) (2) (3) (4) (5) (6) (7) ( (9) (0)) p/s: The CODE tag font lowercase "L" is very similar number "1", can't differentiate in a glance?! Edited June 25, 2014 by hanhphuc Quote Link to comment Share on other sites More sharing options...
ziele_o2k Posted August 19, 2015 Share Posted August 19, 2015 Hi, Can someone help me with my problem? For example, I have list like this: (a 1 2 3 4 a 5 6 7 8 ) and I would like to get something like this: ((1 2 3 4) (5 6 7 8 )) Quote Link to comment Share on other sites More sharing options...
Tharwat Posted August 19, 2015 Share Posted August 19, 2015 Hi, Can someone help me with my problem? For example, I have list like this: (a 1 2 3 4 a 5 6 7 8 ) and I would like to get something like this: ((1 2 3 4) (5 6 7 8 )) What is the criteria that the programmer should consider to come up with this outcome ? Quote Link to comment Share on other sites More sharing options...
ziele_o2k Posted August 19, 2015 Share Posted August 19, 2015 (edited) What is the criteria that the programmer should consider to come up with this outcome ? I would like to divide list by separator. better example below: 1) (setq mylist (list "sep" "a" "b" "c" "sep" "d" "e" "f") or 2) (setq mylist (list "a" "b" "c" "sep" "d" "e" "f") or 3) (setq mylist (list "a" "b" "c" "d" "e" "sep" "f") And now i would like to write function with that will split mylist by separator: (List_sep mylist "sep") Expected result of function List_sep: 1) (("a" "b" "c")("d" "e" "f")) or 2) (("a" "b" "c")("d" "e" "f")) or 3) (("a" "b" "c" "d" "e")("f")) I wrote lisp but it doesn't work: (defun LIST_sep (lista Sep / el res) (setq el "") (foreach % lista (if (wcmatch % (strcat Sep "*")) (setq res (cons el res) el "" ) (if (atom el) (setq el (cons % (list el))) (setq el (cons % el)) ) ) ) (setq res (cons el res)) (vl-remove "" res) ) Edited August 19, 2015 by ziele_o2k Quote Link to comment Share on other sites More sharing options...
Tharwat Posted August 19, 2015 Share Posted August 19, 2015 Try this: (defun _div:by:sep (lst sep / n f out all) ;; Tharwat 19.08.2015 ;; (setq n 0) (repeat (length lst) (while (and (/= (setq f (nth n lst)) sep) f ) (setq out (append out (list f)) n (1+ n) ) ) (if out (setq all (cons out all) out nil ) ) (setq n (1+ n)) ) (reverse all) ) Quote Link to comment Share on other sites More sharing options...
ziele_o2k Posted August 19, 2015 Share Posted August 19, 2015 Thank you. I have to make some changes that lisp will work in case shown below: (setq mylist (list "sepa" "a" "b" "c" "sepa" "d" "e" "f")) (_div:by:sep mylist "se") Result: (("a" "b" "c")("d" "e" "f")) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted August 19, 2015 Share Posted August 19, 2015 Here's another: (defun div ( d l / m r ) (foreach x l (if (= x d) (if m (setq r (cons (reverse m) r) m nil)) (setq m (cons x m)) ) ) (reverse (if m (cons (reverse m) r) r)) ) _$ (div "sep" '("a" "b" "c" "sep" "d" "e" "f")) (("a" "b" "c") ("d" "e" "f")) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted August 19, 2015 Share Posted August 19, 2015 Another, recursive solution: (defun div ( d l / r ) (cond ( (= (car l) d) (div d (cdr l))) ( (setq l (vl-member-if '(lambda ( x ) (setq r (cons x r)) (= x d)) l)) (cons (reverse (cdr r)) (div d (cdr l))) ) ( r (list (reverse r))) ) ) Quote Link to comment Share on other sites More sharing options...
ziele_o2k Posted August 19, 2015 Share Posted August 19, 2015 My version (defun div ( d l / m r ) (foreach x l (if (wcmatch x (strcat d "*")) (if m (setq r (cons (reverse m) r) m nil)) (setq m (cons x m)) ) ) (reverse (if m (cons (reverse m) r) r)) ) (div "se" '("a" "b" "c" "sep" "d" "e" "f")) (("a" "b" "c") ("d" "e" "f")) Quote Link to comment Share on other sites More sharing options...
Tharwat Posted August 19, 2015 Share Posted August 19, 2015 Try this: (defun _div:by:sep (lst sep / n f out all) ;; Tharwat 19.08.2015 ;; (setq n 0) (repeat (length lst) (while (and ([color="blue"]wcmatch [/color](setq f (nth n lst)) sep) f ) (setq out (append out (list f)) n (1+ n) ) ) (if out (setq all (cons out all) out nil ) ) (setq n (1+ n)) ) (reverse all) ) Thank you.I have to make some changes that lisp will work in case shown below: (setq mylist (list "sepa" "a" "b" "c" "sepa" "d" "e" "f")) (_div:by:sep mylist "se") Result: (("a" "b" "c")("d" "e" "f")) I see that you have asked for something else after your first one ! anyway , just replace in my previous program the /= with the wcmatch function as modified in the quotes above. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.