Getting the first n elements of a list in Common Lisp?
14,570
Solution 1
Check out the SUBSEQ
function.
* (equal (subseq '(1 20 300) 0 2)
'(1 20))
T
It may not be immediately obvious, but in Lisp, indexing starts from 0, and you're always taking half-open intervals, so this takes all the elements of the list with indices in the interval [0, 2).
Solution 2
The above answer is of course perfectly correct, but note that if you're using this just to compare against another list, it would be more performance-efficient to walk both lists in-place, rather than consing up a new list just to compare.
For example, in the above case, you might say:
(every #'= '(1 20 300) '(1 20))
=> t
Love,
Author by
Admin
Updated on June 03, 2022Comments
-
Admin almost 2 years
How would I get the first
n
elements of a list?CL-USER> (equal (some-function 2 '(1 20 300)) '(1 20)) T
I am absolutely certain this is elementary, but help a brother newb out.
-
Pillsy over 14 yearsJust use
(loop :repeat a :for x :in b :collect x)
as your function body. Much simpler. -
beggs over 14 yearsThanks... been years since I actually did any lisp. Thought it be fun to answer a question!
-
Rainer Joswig over 14 yearsDefinitely not a good idea to compute the length of a list for getting some elements from the front. Unlispy!
-
Diego Sevilla over 12 yearsThis has the unfortunate restriction that it will fail in runtime if the sequence is smaller than the ending index, which is a pity, because asking for the length before is highly inefficient. So how to proceed in this case?
-
Diego Sevilla over 12 yearsWell, looking at Practical Common Lisp: gigamonkeys.com/book/loop-for-black-belts.html comes the right answer:
(loop for item in list for i from 1 to 10 do (something))
where thatsomething
could be collectingitem
. -
Pillsy over 12 years@DiegoSevilla Sometimes having the code fail at runtime when you don't have enough elements in your list is exactly the behavior you're looking for. A lot of idiomatic Common Lisp code builds fixed-size data structures out of conses instead of using
DEFCLASS
orDEFSTRUCT
, and in those instances, if you don't have enough elements, getting tossed into the debugger immediately is the best thing that can happen to you. -
Svante over 4 yearsThis has some unneeded overhead because it has to walk the entire list to determine the list length first. It will even fail if the list is circular.