summaryrefslogtreecommitdiff
path: root/devdocs/elisp/association-lists.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/elisp/association-lists.html
new repository
Diffstat (limited to 'devdocs/elisp/association-lists.html')
-rw-r--r--devdocs/elisp/association-lists.html148
1 files changed, 148 insertions, 0 deletions
diff --git a/devdocs/elisp/association-lists.html b/devdocs/elisp/association-lists.html
new file mode 100644
index 00000000..1284aea2
--- /dev/null
+++ b/devdocs/elisp/association-lists.html
@@ -0,0 +1,148 @@
+ <h3 class="section">Association Lists</h3> <p>An <em>association list</em>, or <em>alist</em> for short, records a mapping from keys to values. It is a list of cons cells called <em>associations</em>: the <small>CAR</small> of each cons cell is the <em>key</em>, and the <small>CDR</small> is the <em>associated value</em>.<a id="DOCF6" href="#FOOT6"><sup>6</sup></a> </p> <p>Here is an example of an alist. The key <code>pine</code> is associated with the value <code>cones</code>; the key <code>oak</code> is associated with <code>acorns</code>; and the key <code>maple</code> is associated with <code>seeds</code>. </p> <div class="example"> <pre class="example">((pine . cones)
+ (oak . acorns)
+ (maple . seeds))
+</pre>
+</div> <p>Both the values and the keys in an alist may be any Lisp objects. For example, in the following alist, the symbol <code>a</code> is associated with the number <code>1</code>, and the string <code>"b"</code> is associated with the <em>list</em> <code>(2 3)</code>, which is the <small>CDR</small> of the alist element: </p> <div class="example"> <pre class="example">((a . 1) ("b" 2 3))
+</pre>
+</div> <p>Sometimes it is better to design an alist to store the associated value in the <small>CAR</small> of the <small>CDR</small> of the element. Here is an example of such an alist: </p> <div class="example"> <pre class="example">((rose red) (lily white) (buttercup yellow))
+</pre>
+</div> <p>Here we regard <code>red</code> as the value associated with <code>rose</code>. One advantage of this kind of alist is that you can store other related information—even a list of other items—in the <small>CDR</small> of the <small>CDR</small>. One disadvantage is that you cannot use <code>rassq</code> (see below) to find the element containing a given value. When neither of these considerations is important, the choice is a matter of taste, as long as you are consistent about it for any given alist. </p> <p>The same alist shown above could be regarded as having the associated value in the <small>CDR</small> of the element; the value associated with <code>rose</code> would be the list <code>(red)</code>. </p> <p>Association lists are often used to record information that you might otherwise keep on a stack, since new associations may be added easily to the front of the list. When searching an association list for an association with a given key, the first one found is returned, if there is more than one. </p> <p>In Emacs Lisp, it is <em>not</em> an error if an element of an association list is not a cons cell. The alist search functions simply ignore such elements. Many other versions of Lisp signal errors in such cases. </p> <p>Note that property lists are similar to association lists in several respects. A property list behaves like an association list in which each key can occur only once. See <a href="property-lists">Property Lists</a>, for a comparison of property lists and association lists. </p> <dl> <dt id="assoc">Function: <strong>assoc</strong> <em>key alist &amp;optional testfn</em>
+</dt> <dd>
+<p>This function returns the first association for <var>key</var> in <var>alist</var>, comparing <var>key</var> against the alist elements using <var>testfn</var> if it is a function, and <code>equal</code> otherwise (see <a href="equality-predicates">Equality Predicates</a>). If <var>testfn</var> is a function, it is called with two arguments: the <small>CAR</small> of an element from <var>alist</var> and <var>key</var>. The function returns <code>nil</code> if no association in <var>alist</var> has a <small>CAR</small> equal to <var>key</var>, as tested by <var>testfn</var>. For example: </p> <div class="example"> <pre class="example">(setq trees '((pine . cones) (oak . acorns) (maple . seeds)))
+ ⇒ ((pine . cones) (oak . acorns) (maple . seeds))
+(assoc 'oak trees)
+ ⇒ (oak . acorns)
+(cdr (assoc 'oak trees))
+ ⇒ acorns
+(assoc 'birch trees)
+ ⇒ nil
+</pre>
+</div> <p>Here is another example, in which the keys and values are not symbols: </p> <div class="example"> <pre class="example">(setq needles-per-cluster
+ '((2 "Austrian Pine" "Red Pine")
+ (3 "Pitch Pine")
+ (5 "White Pine")))
+
+(cdr (assoc 3 needles-per-cluster))
+ ⇒ ("Pitch Pine")
+(cdr (assoc 2 needles-per-cluster))
+ ⇒ ("Austrian Pine" "Red Pine")
+</pre>
+</div> </dd>
+</dl> <p>The function <code>assoc-string</code> is much like <code>assoc</code> except that it ignores certain differences between strings. See <a href="text-comparison">Text Comparison</a>. </p> <dl> <dt id="rassoc">Function: <strong>rassoc</strong> <em>value alist</em>
+</dt> <dd>
+<p>This function returns the first association with value <var>value</var> in <var>alist</var>. It returns <code>nil</code> if no association in <var>alist</var> has a <small>CDR</small> <code>equal</code> to <var>value</var>. </p> <p><code>rassoc</code> is like <code>assoc</code> except that it compares the <small>CDR</small> of each <var>alist</var> association instead of the <small>CAR</small>. You can think of this as reverse <code>assoc</code>, finding the key for a given value. </p>
+</dd>
+</dl> <dl> <dt id="assq">Function: <strong>assq</strong> <em>key alist</em>
+</dt> <dd>
+<p>This function is like <code>assoc</code> in that it returns the first association for <var>key</var> in <var>alist</var>, but it makes the comparison using <code>eq</code>. <code>assq</code> returns <code>nil</code> if no association in <var>alist</var> has a <small>CAR</small> <code>eq</code> to <var>key</var>. This function is used more often than <code>assoc</code>, since <code>eq</code> is faster than <code>equal</code> and most alists use symbols as keys. See <a href="equality-predicates">Equality Predicates</a>. </p> <div class="example"> <pre class="example">(setq trees '((pine . cones) (oak . acorns) (maple . seeds)))
+ ⇒ ((pine . cones) (oak . acorns) (maple . seeds))
+(assq 'pine trees)
+ ⇒ (pine . cones)
+</pre>
+</div> <p>On the other hand, <code>assq</code> is not usually useful in alists where the keys may not be symbols: </p> <div class="example"> <pre class="example">(setq leaves
+ '(("simple leaves" . oak)
+ ("compound leaves" . horsechestnut)))
+
+(assq "simple leaves" leaves)
+ ⇒ <span class="roman">Unspecified; might be <code>nil</code> or <code>("simple leaves" . oak)</code>.</span>
+(assoc "simple leaves" leaves)
+ ⇒ ("simple leaves" . oak)
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="alist-get">Function: <strong>alist-get</strong> <em>key alist &amp;optional default remove testfn</em>
+</dt> <dd>
+<p>This function is similar to <code>assq</code>. It finds the first association <code>(<var>key</var> . <var>value</var>)</code> by comparing <var>key</var> with <var>alist</var> elements, and, if found, returns the <var>value</var> of that association. If no association is found, the function returns <var>default</var>. Comparison of <var>key</var> against <var>alist</var> elements uses the function specified by <var>testfn</var>, defaulting to <code>eq</code>. </p> <p>This is a generalized variable (see <a href="generalized-variables">Generalized Variables</a>) that can be used to change a value with <code>setf</code>. When using it to set a value, optional argument <var>remove</var> non-<code>nil</code> means to remove <var>key</var>’s association from <var>alist</var> if the new value is <code>eql</code> to <var>default</var>. </p>
+</dd>
+</dl> <dl> <dt id="rassq">Function: <strong>rassq</strong> <em>value alist</em>
+</dt> <dd>
+<p>This function returns the first association with value <var>value</var> in <var>alist</var>. It returns <code>nil</code> if no association in <var>alist</var> has a <small>CDR</small> <code>eq</code> to <var>value</var>. </p> <p><code>rassq</code> is like <code>assq</code> except that it compares the <small>CDR</small> of each <var>alist</var> association instead of the <small>CAR</small>. You can think of this as reverse <code>assq</code>, finding the key for a given value. </p> <p>For example: </p> <div class="example"> <pre class="example">(setq trees '((pine . cones) (oak . acorns) (maple . seeds)))
+
+(rassq 'acorns trees)
+ ⇒ (oak . acorns)
+(rassq 'spores trees)
+ ⇒ nil
+</pre>
+</div> <p><code>rassq</code> cannot search for a value stored in the <small>CAR</small> of the <small>CDR</small> of an element: </p> <div class="example"> <pre class="example">(setq colors '((rose red) (lily white) (buttercup yellow)))
+
+(rassq 'white colors)
+ ⇒ nil
+</pre>
+</div> <p>In this case, the <small>CDR</small> of the association <code>(lily white)</code> is not the symbol <code>white</code>, but rather the list <code>(white)</code>. This becomes clearer if the association is written in dotted pair notation: </p> <div class="example"> <pre class="example">(lily white) ≡ (lily . (white))
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="assoc-default">Function: <strong>assoc-default</strong> <em>key alist &amp;optional test default</em>
+</dt> <dd>
+<p>This function searches <var>alist</var> for a match for <var>key</var>. For each element of <var>alist</var>, it compares the element (if it is an atom) or the element’s <small>CAR</small> (if it is a cons) against <var>key</var>, by calling <var>test</var> with two arguments: the element or its <small>CAR</small>, and <var>key</var>. The arguments are passed in that order so that you can get useful results using <code>string-match</code> with an alist that contains regular expressions (see <a href="regexp-search">Regexp Search</a>). If <var>test</var> is omitted or <code>nil</code>, <code>equal</code> is used for comparison. </p> <p>If an alist element matches <var>key</var> by this criterion, then <code>assoc-default</code> returns a value based on this element. If the element is a cons, then the value is the element’s <small>CDR</small>. Otherwise, the return value is <var>default</var>. </p> <p>If no alist element matches <var>key</var>, <code>assoc-default</code> returns <code>nil</code>. </p>
+</dd>
+</dl> <dl> <dt id="copy-alist">Function: <strong>copy-alist</strong> <em>alist</em>
+</dt> <dd>
+ <p>This function returns a two-level deep copy of <var>alist</var>: it creates a new copy of each association, so that you can alter the associations of the new alist without changing the old one. </p> <div class="example"> <pre class="example">(setq needles-per-cluster
+ '((2 . ("Austrian Pine" "Red Pine"))
+ (3 . ("Pitch Pine"))
+</pre>
+<pre class="example"> (5 . ("White Pine"))))
+⇒
+((2 "Austrian Pine" "Red Pine")
+ (3 "Pitch Pine")
+ (5 "White Pine"))
+
+(setq copy (copy-alist needles-per-cluster))
+⇒
+((2 "Austrian Pine" "Red Pine")
+ (3 "Pitch Pine")
+ (5 "White Pine"))
+
+(eq needles-per-cluster copy)
+ ⇒ nil
+(equal needles-per-cluster copy)
+ ⇒ t
+(eq (car needles-per-cluster) (car copy))
+ ⇒ nil
+(cdr (car (cdr needles-per-cluster)))
+ ⇒ ("Pitch Pine")
+</pre>
+<pre class="example">(eq (cdr (car (cdr needles-per-cluster)))
+ (cdr (car (cdr copy))))
+ ⇒ t
+</pre>
+</div> <p>This example shows how <code>copy-alist</code> makes it possible to change the associations of one copy without affecting the other: </p> <div class="example"> <pre class="example">(setcdr (assq 3 copy) '("Martian Vacuum Pine"))
+(cdr (assq 3 needles-per-cluster))
+ ⇒ ("Pitch Pine")
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="assq-delete-all">Function: <strong>assq-delete-all</strong> <em>key alist</em>
+</dt> <dd>
+<p>This function deletes from <var>alist</var> all the elements whose <small>CAR</small> is <code>eq</code> to <var>key</var>, much as if you used <code>delq</code> to delete each such element one by one. It returns the shortened alist, and often modifies the original list structure of <var>alist</var>. For correct results, use the return value of <code>assq-delete-all</code> rather than looking at the saved value of <var>alist</var>. </p> <div class="example"> <pre class="example">(setq alist (list '(foo 1) '(bar 2) '(foo 3) '(lose 4)))
+ ⇒ ((foo 1) (bar 2) (foo 3) (lose 4))
+(assq-delete-all 'foo alist)
+ ⇒ ((bar 2) (lose 4))
+alist
+ ⇒ ((foo 1) (bar 2) (lose 4))
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="assoc-delete-all">Function: <strong>assoc-delete-all</strong> <em>key alist &amp;optional test</em>
+</dt> <dd><p>This function is like <code>assq-delete-all</code> except that it accepts an optional argument <var>test</var>, a predicate function to compare the keys in <var>alist</var>. If omitted or <code>nil</code>, <var>test</var> defaults to <code>equal</code>. As <code>assq-delete-all</code>, this function often modifies the original list structure of <var>alist</var>. </p></dd>
+</dl> <dl> <dt id="rassq-delete-all">Function: <strong>rassq-delete-all</strong> <em>value alist</em>
+</dt> <dd><p>This function deletes from <var>alist</var> all the elements whose <small>CDR</small> is <code>eq</code> to <var>value</var>. It returns the shortened alist, and often modifies the original list structure of <var>alist</var>. <code>rassq-delete-all</code> is like <code>assq-delete-all</code> except that it compares the <small>CDR</small> of each <var>alist</var> association instead of the <small>CAR</small>. </p></dd>
+</dl> <dl> <dt id="let-alist">Macro: <strong>let-alist</strong> <em>alist body</em>
+</dt> <dd>
+<p>Creates a binding for each symbol used as keys the association list <var>alist</var>, prefixed with dot. This can be useful when accessing several items in the same association list, and it’s best understood through a simple example: </p> <div class="lisp"> <pre class="lisp">(setq colors '((rose . red) (lily . white) (buttercup . yellow)))
+(let-alist colors
+ (if (eq .rose 'red)
+ .lily))
+ ⇒ white
+</pre>
+</div> <p>The <var>body</var> is inspected at compilation time, and only the symbols that appear in <var>body</var> with a ‘<samp>.</samp>’ as the first character in the symbol name will be bound. Finding the keys is done with <code>assq</code>, and the <code>cdr</code> of the return value of this <code>assq</code> is assigned as the value for the binding. </p> <p>Nested association lists is supported: </p> <div class="lisp"> <pre class="lisp">(setq colors '((rose . red) (lily (belladonna . yellow) (brindisi . pink))))
+(let-alist colors
+ (if (eq .rose 'red)
+ .lily.belladonna))
+ ⇒ yellow
+</pre>
+</div> <p>Nesting <code>let-alist</code> inside each other is allowed, but the code in the inner <code>let-alist</code> can’t access the variables bound by the outer <code>let-alist</code>. </p>
+</dd>
+</dl><div class="_attribution">
+ <p class="_attribution-p">
+ Copyright &copy; 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br>
+ <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html</a>
+ </p>
+</div>