Cómo INSERTAR un valor en una lista existente dentro de una tabla hash.
Estoy intentando escribir una función que agregue datos a una tabla hash. La función toma una clave y un valor. Si la clave dada ya existe en la tabla, se agrega el valor dado a los valores existentes asociados con la clave. Si la clave aún no existe en la tabla, el valor se coloca en una lista y se agrega a la tabla. Aquí está la implementación:
(defparameter <em>ht</em> (make-hash-table))
(defun add-to-table (key value)
(multiple-value-bind (existing-values present-p) (gethash key <em>ht</em>)
(if present-p
(push value existing-values)
(setf (gethash key <em>ht</em>) (list value)))))
Intenté usar la función de la siguiente manera:
(add-to-table 'company "Acme")
(add-to-table 'company "Ajax")
Sin embargo, (length (gethash 'company *ht*))
devuelve 1
en lugar de 2
, a pesar de que agregué dos empresas. ¿Por qué es eso?
Descubrí que podría solucionar el problema reemplazando (push value existing-values)
con (push value (gethash key *ht*))
. ¿Por qué necesito usar otro (gethash key *ht*)
cuando ya he obtenido su valor (existing-values
)? ¿No se supone que existing-values
es una especie de puntero a la lista?
davy.ai
La razón por la que
(push value existing-values)
no funciona es queexisting-values
es una copia de la lista asociada con la clave en la tabla hash. Cuando modificasexisting-values
conpush
, no estás modificando la lista en la tabla hash misma. Por lo tanto, necesitas usar(gethash key *ht*)
para obtener una referencia a la lista actual en la tabla hash y modificarla conpush
.En Lisp, las variables suelen ser referencias a objetos en lugar de punteros. Cuando asignas un valor a una variable, estás copiando la referencia al objeto, no el objeto en sí. Por lo tanto,
existing-values
es una referencia a la lista en la tabla hash, pero no es la misma referencia que(gethash key *ht*)
. Al utilizar(push value (gethash key *ht*))
, estás modificando la lista real en la tabla hash, lo cual es lo que deseas hacer.