Reputation: 962
I wanted to split a sequence using LOOP
.
I thought the easiest way would be a loop collecting all elements, but this seems not to be possible with loop.
It would look this way:
(loop for i in '(1 2 3 4 5) with-rest rest
if (not (= i 3))
collect i
else
return (values i rest))
It should return the values (1 2)
and (3 4 5)
(or maybe (4 5)
as second value).
Is there a keyword in loop that can do this (or in the iterate system), or is this only possible by writing new macros (or using tagbody)?
Upvotes: 1
Views: 233
Reputation: 11854
One terse option that avoids LOOP, but traverses part of the list twice:
(let ((tail (member 3 list)))
(values (ldiff tail list) tail))
Upvotes: 2
Reputation: 139261
LOOP
can destructure lists into head and tail. Then one would not use in
, but on
. You can also collect into a variable.
CL-USER 13 > (loop for (i . rest) on '(1 2 3 4 5)
if (not (= i 3))
collect i into head
else return (values head (cons i rest)))
(1 2)
(3 4 5)
or
CL-USER 16 > (loop with list = '(1 2 3 4 5)
for i in list
for rest on (rest list)
if (not (= i 3))
collect i into head
else return (values head (cons i rest)))
(1 2)
(3 4 5)
Upvotes: 3