Jump to content

Recommended Posts

Posted

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

Posted

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.

Posted (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 by ymg3
Posted

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))

Posted (edited)

@ymg & LM :thumbsup:

 

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 by hanhphuc
  • 1 year later...
Posted

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 ))

Posted
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 ?

Posted (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 by ziele_o2k
Posted

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)
 )

Posted

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"))

Posted

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"))

Posted

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)))
   )
)

Posted

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"))

Posted
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.

  • 8 years later...
Posted

;;;n - L1 length

;;;L - list

(defun BreakAtN (L n / L1 L2)

  (setq L2 L)

  (repeat n (setq L1 (cons (car L2) L1) L2 (cdr L2)))

)

 

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...