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.
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.
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).
(loop for item in list for i from 1 to 10 do (something))
where that something
could be collecting item
. –
Custommade DEFCLASS
or DEFSTRUCT
, 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. –
Pyrimidine 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
Tinkering with the core CL functionalities:
(defun first-n (n list)
"Returns the first N elements of the LIST."
(butlast list (- (list-length list) n)))
(first-n 2 '(a s d f g)) ;(A S)
Recursive:
(defun first-n (list n)
"Returns the first n elements of the list."
(when (not (zerop n))
(cons (first list) (first-n (rest list) (1- n)))))
(first-n '(a b c d e) 3) ;(A B C)
With loop
:
(defun first-n-loop (list n)
"Returns first n elements of the list."
(loop for i below n
collect (nth i list)))
(first-n-loop '(a b c d e) 3) ;(A B C)
(loop :repeat n :for x :in list :collect x)
. –
Orobanchaceous @Pillsy has the answer. SUBSEQ.
But there is a difficulty with SUBSEQ that if you specify beyond the end of the list, you get an error. This is overcome by using LENGTH and MIN:
(defun first-n (n lst)
(subseq lst 0 (min (length lst) n)))
For example:
CL-USER 11 > (first-n 3 (list 1 2 3 4 5 6 6))
(1 2 3)
CL-USER 16 > (first-n 10 '(1 2 3 4 5 6 6))
(1 2 3 4 5 6 6)
Had to download a lisp command line... but:
(defun head-x (a b)
(loop for x from 1 to a
for y = (car b) do
(setq b (cdr b))
collect y))
so:
(head-x 2 '(a b c d))
'(a b)
(loop :repeat a :for x :in b :collect x)
as your function body. Much simpler. –
Pyrimidine (defun pncar (n L)
(setq L_ (list (nth 0 L)))
(setq i 0)
(if (and (< n 1) (< n (length L)))
(setq L_ '())
(repeat (- n 1) (progn
(setq i (+ i 1))
(if (/= nil (nth i L))
(setq L_ (append (list (nth i L)) L_))
(setq L_ '())
)
)
)
)
(setq L_ (reverse L_))
)
Examples:
(pncar 0 '(0 1 2 3))
nil
(pncar 1 '(0 1 2 3))
(0)
(pncar 2 '(0 1 2 3))
(0 1)
(pncar 3 '(0 1 2 3))
(0 1 2)
(pncar 4 '(0 1 2 3))
(0 1 2 3)
(pncar 5 '(0 1 2 3))
nil
(butlast '(1 20 300) (- (list-length '(1 20 300)) 2))
Should be made into a function/macro.
P.S. This page might be useful. See function 'extrude'.
© 2022 - 2024 — McMap. All rights reserved.