diff options
Diffstat (limited to 'devdocs/elisp/sets-and-lists.html')
| -rw-r--r-- | devdocs/elisp/sets-and-lists.html | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/devdocs/elisp/sets-and-lists.html b/devdocs/elisp/sets-and-lists.html new file mode 100644 index 00000000..4f218f1b --- /dev/null +++ b/devdocs/elisp/sets-and-lists.html @@ -0,0 +1,112 @@ + <h3 class="section">Using Lists as Sets</h3> <p>A list can represent an unordered mathematical set—simply consider a value an element of a set if it appears in the list, and ignore the order of the list. To form the union of two sets, use <code>append</code> (as long as you don’t mind having duplicate elements). You can remove <code>equal</code> duplicates using <code>delete-dups</code> or <code>seq-uniq</code>. Other useful functions for sets include <code>memq</code> and <code>delq</code>, and their <code>equal</code> versions, <code>member</code> and <code>delete</code>. </p> <blockquote> <p><b>Common Lisp note:</b> Common Lisp has functions <code>union</code> (which avoids duplicate elements) and <code>intersection</code> for set operations. In Emacs Lisp, variants of these facilities are provided by the <samp>cl-lib</samp> library. See <a href="https://www.gnu.org/software/emacs/manual/html_node/cl/Lists-as-Sets.html#Lists-as-Sets">Lists as Sets</a> in <cite>Common Lisp Extensions</cite>. </p> +</blockquote> <dl> <dt id="memq">Function: <strong>memq</strong> <em>object list</em> +</dt> <dd> + <p>This function tests to see whether <var>object</var> is a member of <var>list</var>. If it is, <code>memq</code> returns a list starting with the first occurrence of <var>object</var>. Otherwise, it returns <code>nil</code>. The letter ‘<samp>q</samp>’ in <code>memq</code> says that it uses <code>eq</code> to compare <var>object</var> against the elements of the list. For example: </p> <div class="example"> <pre class="example">(memq 'b '(a b c b a)) + ⇒ (b c b a) +</pre> +<pre class="example">(memq '(2) '((1) (2))) ; <span class="roman">The two <code>(2)</code>s need not be <code>eq</code>.</span> + ⇒ <span class="roman">Unspecified; might be <code>nil</code> or <code>((2))</code>.</span> +</pre> +</div> </dd> +</dl> <dl> <dt id="delq">Function: <strong>delq</strong> <em>object list</em> +</dt> <dd> + <p>This function destructively removes all elements <code>eq</code> to <var>object</var> from <var>list</var>, and returns the resulting list. The letter ‘<samp>q</samp>’ in <code>delq</code> says that it uses <code>eq</code> to compare <var>object</var> against the elements of the list, like <code>memq</code> and <code>remq</code>. </p> <p>Typically, when you invoke <code>delq</code>, you should use the return value by assigning it to the variable which held the original list. The reason for this is explained below. </p> +</dd> +</dl> <p>The <code>delq</code> function deletes elements from the front of the list by simply advancing down the list, and returning a sublist that starts after those elements. For example: </p> <div class="example"> <pre class="example">(delq 'a '(a b c)) ≡ (cdr '(a b c)) +</pre> +</div> <p>When an element to be deleted appears in the middle of the list, removing it involves changing the <small>CDR</small>s (see <a href="setcdr">Setcdr</a>). </p> <div class="example"> <pre class="example">(setq sample-list (list 'a 'b 'c '(4))) + ⇒ (a b c (4)) +</pre> +<pre class="example">(delq 'a sample-list) + ⇒ (b c (4)) +</pre> +<pre class="example">sample-list + ⇒ (a b c (4)) +</pre> +<pre class="example">(delq 'c sample-list) + ⇒ (a b (4)) +</pre> +<pre class="example">sample-list + ⇒ (a b (4)) +</pre> +</div> <p>Note that <code>(delq 'c sample-list)</code> modifies <code>sample-list</code> to splice out the third element, but <code>(delq 'a sample-list)</code> does not splice anything—it just returns a shorter list. Don’t assume that a variable which formerly held the argument <var>list</var> now has fewer elements, or that it still holds the original list! Instead, save the result of <code>delq</code> and use that. Most often we store the result back into the variable that held the original list: </p> <div class="example"> <pre class="example">(setq flowers (delq 'rose flowers)) +</pre> +</div> <p>In the following example, the <code>(list 4)</code> that <code>delq</code> attempts to match and the <code>(4)</code> in the <code>sample-list</code> are <code>equal</code> but not <code>eq</code>: </p> <div class="example"> <pre class="example">(delq (list 4) sample-list) + ⇒ (a c (4)) +</pre> +</div> <p>If you want to delete elements that are <code>equal</code> to a given value, use <code>delete</code> (see below). </p> <dl> <dt id="remq">Function: <strong>remq</strong> <em>object list</em> +</dt> <dd> +<p>This function returns a copy of <var>list</var>, with all elements removed which are <code>eq</code> to <var>object</var>. The letter ‘<samp>q</samp>’ in <code>remq</code> says that it uses <code>eq</code> to compare <var>object</var> against the elements of <code>list</code>. </p> <div class="example"> <pre class="example">(setq sample-list (list 'a 'b 'c 'a 'b 'c)) + ⇒ (a b c a b c) +</pre> +<pre class="example">(remq 'a sample-list) + ⇒ (b c b c) +</pre> +<pre class="example">sample-list + ⇒ (a b c a b c) +</pre> +</div> </dd> +</dl> <dl> <dt id="memql">Function: <strong>memql</strong> <em>object list</em> +</dt> <dd> +<p>The function <code>memql</code> tests to see whether <var>object</var> is a member of <var>list</var>, comparing members with <var>object</var> using <code>eql</code>, so floating-point elements are compared by value. If <var>object</var> is a member, <code>memql</code> returns a list starting with its first occurrence in <var>list</var>. Otherwise, it returns <code>nil</code>. </p> <p>Compare this with <code>memq</code>: </p> <div class="example"> <pre class="example">(memql 1.2 '(1.1 1.2 1.3)) ; <span class="roman"><code>1.2</code> and <code>1.2</code> are <code>eql</code>.</span> + ⇒ (1.2 1.3) +</pre> +<pre class="example">(memq 1.2 '(1.1 1.2 1.3)) ; <span class="roman">The two <code>1.2</code>s need not be <code>eq</code>.</span> + ⇒ <span class="roman">Unspecified; might be <code>nil</code> or <code>(1.2 1.3)</code>.</span> +</pre> +</div> </dd> +</dl> <p>The following three functions are like <code>memq</code>, <code>delq</code> and <code>remq</code>, but use <code>equal</code> rather than <code>eq</code> to compare elements. See <a href="equality-predicates">Equality Predicates</a>. </p> <dl> <dt id="member">Function: <strong>member</strong> <em>object list</em> +</dt> <dd> +<p>The function <code>member</code> tests to see whether <var>object</var> is a member of <var>list</var>, comparing members with <var>object</var> using <code>equal</code>. If <var>object</var> is a member, <code>member</code> returns a list starting with its first occurrence in <var>list</var>. Otherwise, it returns <code>nil</code>. </p> <p>Compare this with <code>memq</code>: </p> <div class="example"> <pre class="example">(member '(2) '((1) (2))) ; <span class="roman"><code>(2)</code> and <code>(2)</code> are <code>equal</code>.</span> + ⇒ ((2)) +</pre> +<pre class="example">(memq '(2) '((1) (2))) ; <span class="roman">The two <code>(2)</code>s need not be <code>eq</code>.</span> + ⇒ <span class="roman">Unspecified; might be <code>nil</code> or <code>(2)</code>.</span> +</pre> +<pre class="example">;; <span class="roman">Two strings with the same contents are <code>equal</code>.</span> +(member "foo" '("foo" "bar")) + ⇒ ("foo" "bar") +</pre> +</div> </dd> +</dl> <dl> <dt id="delete">Function: <strong>delete</strong> <em>object sequence</em> +</dt> <dd> +<p>This function removes all elements <code>equal</code> to <var>object</var> from <var>sequence</var>, and returns the resulting sequence. </p> <p>If <var>sequence</var> is a list, <code>delete</code> is to <code>delq</code> as <code>member</code> is to <code>memq</code>: it uses <code>equal</code> to compare elements with <var>object</var>, like <code>member</code>; when it finds an element that matches, it cuts the element out just as <code>delq</code> would. As with <code>delq</code>, you should typically use the return value by assigning it to the variable which held the original list. </p> <p>If <code>sequence</code> is a vector or string, <code>delete</code> returns a copy of <code>sequence</code> with all elements <code>equal</code> to <code>object</code> removed. </p> <p>For example: </p> <div class="example"> <pre class="example">(setq l (list '(2) '(1) '(2))) +(delete '(2) l) + ⇒ ((1)) +l + ⇒ ((2) (1)) +;; <span class="roman">If you want to change <code>l</code> reliably,</span> +;; <span class="roman">write <code>(setq l (delete '(2) l))</code>.</span> +</pre> +<pre class="example">(setq l (list '(2) '(1) '(2))) +(delete '(1) l) + ⇒ ((2) (2)) +l + ⇒ ((2) (2)) +;; <span class="roman">In this case, it makes no difference whether you set <code>l</code>,</span> +;; <span class="roman">but you should do so for the sake of the other case.</span> +</pre> +<pre class="example">(delete '(2) [(2) (1) (2)]) + ⇒ [(1)] +</pre> +</div> </dd> +</dl> <dl> <dt id="remove">Function: <strong>remove</strong> <em>object sequence</em> +</dt> <dd> +<p>This function is the non-destructive counterpart of <code>delete</code>. It returns a copy of <code>sequence</code>, a list, vector, or string, with elements <code>equal</code> to <code>object</code> removed. For example: </p> <div class="example"> <pre class="example">(remove '(2) '((2) (1) (2))) + ⇒ ((1)) +</pre> +<pre class="example">(remove '(2) [(2) (1) (2)]) + ⇒ [(1)] +</pre> +</div> </dd> +</dl> <blockquote> <p><b>Common Lisp note:</b> The functions <code>member</code>, <code>delete</code> and <code>remove</code> in GNU Emacs Lisp are derived from Maclisp, not Common Lisp. The Common Lisp versions do not use <code>equal</code> to compare elements. </p> +</blockquote> <dl> <dt id="member-ignore-case">Function: <strong>member-ignore-case</strong> <em>object list</em> +</dt> <dd><p>This function is like <code>member</code>, except that <var>object</var> should be a string and that it ignores differences in letter-case and text representation: upper-case and lower-case letters are treated as equal, and unibyte strings are converted to multibyte prior to comparison. </p></dd> +</dl> <dl> <dt id="delete-dups">Function: <strong>delete-dups</strong> <em>list</em> +</dt> <dd><p>This function destructively removes all <code>equal</code> duplicates from <var>list</var>, stores the result in <var>list</var> and returns it. Of several <code>equal</code> occurrences of an element in <var>list</var>, <code>delete-dups</code> keeps the first one. See <code>seq-uniq</code> for non-destructive operation (see <a href="sequence-functions">Sequence Functions</a>). </p></dd> +</dl> <p>See also the function <code>add-to-list</code>, in <a href="list-variables">List Variables</a>, for a way to add an element to a list stored in a variable and used as a set. </p><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 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/Sets-And-Lists.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Sets-And-Lists.html</a> + </p> +</div> |
