What data structure you use depends on how you will be using it, in particular, how you will be accessing and setting its parts.
If you have no special needs in this regard, consider starting with an alist. In that case, there is typically no reason to prefer an element such as (Hank (0.1.09.1999 . Syracuse))
to an element such as (Hank 0.1.09.1999 . Syracuse)
(or even just (Hank 0.1.09.1999 Syracuse)
. All of these associate the key Hank
with 0.1.09.1999
and Syracuse
, but in different ways.
If you are not already, become familiar with how to access elements of a list (a cons, really), starting with car
and cdr
, but including also nth
and nthcdr
. (An alist is just a list whose elements are conses.)
Once you know how to grab the content you want from an alist element, and you know how to get the alist element you want, you can consider, for convenience and readability, writing accessor macros.
For example, if your alist elements look like (Hank 0.1.09.1999 Syracuse)
then here are some accessor macros:
(defmacro name (triplet)
`(car ,triplet))
(defmacro date (triplet)
`(cadr ,triplet))
(defmacro location (triplet)
`(car (cddr ,triplet)))
Note that you get this kind of thing (and much more) if you use defstruct
. But note too that an alist can have multiple entries that have the same key (e.g. multiple entries with key Hank
) -- this is undefined for defstruct
(in some implementations it raises an error).
For most purposes (e.g. access by assq
or assoc
), the first matching entry shadows the others. But you can, if you want, create and use alists that have entries with identical keys but different values, and this can be useful, depending on the application.
Really, to repeat, what kind of structure you use depends on how you use it, including how easily you want to be able to add, delete, or modify entries, whether the structure needs to be ordered. (Think of the differences in use between vectors, lists, and hash tables, for instance.)