Получение первых n элементов списка в Common Lisp?

Как мне получить первые n элементы списка?

CL-USER> (equal (some-function 2 '(1 20 300))
                '(1 20))
T

Я абсолютно уверен, что это элементарно, но помогите брату newb.

Ответ 1

Проверьте SUBSEQ.

* (equal (subseq '(1 20 300) 0 2)
         '(1 20))
T

Это может быть не сразу очевидным, но в Lisp индексирование начинается с 0, и вы всегда принимаете полуоткрытые интервалы, поэтому это принимает все элементы списка с индексами в интервале [0, 2).

Ответ 2

Вышеприведенный ответ, конечно, совершенно правильный, но обратите внимание, что если вы используете это только для сравнения с другим списком, было бы более эффективно работать с обоими списками на месте, а не задумываться о новом списке просто для сравнения.

Например, в приведенном выше случае вы можете сказать:

(every #'= '(1 20 300) '(1 20))
=> t

Любовь,

Ответ 3

Рекурсивный:

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

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

Ответ 4

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

Примеры:

(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

Ответ 5

Пришлось загрузить командную строку lisp... но:

(defun head-x (a b)
   (loop for x from 1 to a 
         for y = (car b) do 
            (setq b (cdr b)) 
         collect y))

так:

(head-x 2 '(a b c d))
  '(a b)

Ответ 6

(butlast '(1 20 300) (- (длина списка' (1 20 300)) 2))

Должно быть сделано в функцию/макрос.

P.S. Эта страница может быть полезна. См. Функцию "extrude".