P: Cómo eliminar / eliminar el enésimo elemento de una lista.
PRECAUCIÓN : no elimine todas las ocurrencias / miembros que coincidan con el enésimo elemento, por ejemplo, eq
o equal
.
EJEMPLO : Eliminar el elemento 17 de:
'(a b c d e f g h i j k l m n o p q r s t u v w x y z)
Enésimo elemento - Hoja de trucos / leyenda :
element 0: a
element 1: b
element 2: c
element 3: d
element 4: e
element 5: f
element 6: g
element 7: h
element 8: i
element 9: j
element 10: k
element 11: l
element 12: m
element 13: n
element 14: o
element 15: p
element 16: q
element 17: r
element 18: s
element 19: t
element 20: u
element 21: v
element 22: w
element 23: x
element 24: y
element 25: z
(cons nil nil)
es un poco más barato quegensym
ya que en realidad no necesitas un símbolo aquí.Aquí hay una función simple para eliminar el enésimo elemento de una lista:
Dos notas: requiere
cl-lib
, y no es terriblemente eficiente, ya que recorre la lista varias veces. Este último probablemente solo sea notable para largas listas.Aquí hay versiones destructivas y no destructivas que no requieren
cl-lib
(nuevamente, no son terriblemente eficientes):fuente
cl-subseq
desde lacl-lib
biblioteca.nthcdr
ganaste con el camino ;-). Solo lo vi en la segunda mirada. Borré mi respuesta ...Aquí hay otra versión no destructiva que utiliza
cl-loop
:fuente
Aquí hay una respuesta usando solo recursividad. Primero verificamos si la lista está vacía, en cuyo caso devolvemos la lista vacía. A continuación, comprobamos para ver si vamos a eliminar el 0 º elemento de la lista, en cuyo caso todo lo que queremos es el
cdr
de la lista. Si no hemos golpeado uno de esos casos base, recurrimos al eliminar el n-1 º elemento de lacdr
de la lista, y luegocons
lacar
de la lista original en el resultado de la llamada recursiva.Debería ser muy eficiente. Se ejecuta en tiempo lineal.
fuente
Sorprendido de ver
cl-delete/remove-if
no fue mencionado:Este es un tiempo lineal, y debería ser razonablemente eficiente, aunque espero que sea un poco más lento que la respuesta de wvxvw, ya que pasa por algunas rutas de código más genéricas.
fuente
No estaba contento con la respuesta aceptada porque no parece ser destructiva para nth = 0. Se me ocurrió lo siguiente:
Versión no destructiva:
seq.el
Las funciones son nuevas en emacs 25.1. En versiones anteriores puede que necesiteVersión destructiva, incluso para nth = 0:
fuente
delete-nth-element
no puede funcionar "en el lugar" en el caso dondenum
es 0 ylst
es una lista de un solo elemento.delete-nth-element
, no solo elimina un solo elemento, sino que lo reemplaza connil
, terminando en(nil)
lugar de lo esperado()
. +1.