User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cl:functions:assoc [2019/07/14 17:00]
cl:functions:assoc [2019/07/17 21:00] (current)
Line 1: Line 1:
 +====== Function ASSOC, ASSOC-IF, ASSOC-IF-NOT ======
  
 +====Syntax====
 +  * **assoc ** //item alist ''&​key''​ key test test-not// → //entry//
 +  * **assoc-if ** //predicate alist ''&​key''​ key// → //entry//
 +  * **assoc-if-not** //predicate alist ''&​key''​ key// → //entry//
 +
 +====Arguments and Values====
 +  * //item// - an //​[[CL:​Glossary:​object]]//​.
 +  * //alist// - an //​[[CL:​Glossary:​association list]]//.
 +  * //​predicate//​ - a //​[[CL:​Glossary:​designator]]//​ for  a //​[[CL:​Glossary:​function]]//​ of one //​[[CL:​Glossary:​argument]]//​ that returns a //​[[CL:​Glossary:​generalized boolean]]//​.
 +  * //test// - a //​[[CL:​Glossary:​designator]]//​ for a //​[[CL:​Glossary:​function]]//​ of two //​[[CL:​Glossary:​argument|arguments]]//​ that returns a //​[[CL:​Glossary:​generalized boolean]]//​.
 +  * //​test-not//​ - a //​[[CL:​Glossary:​designator]]//​ for  a //​[[CL:​Glossary:​function]]//​ of two //​[[CL:​Glossary:​argument|arguments]]//​ that returns a //​[[CL:​Glossary:​generalized boolean]]//​.
 +  * //key// - a //​[[CL:​Glossary:​designator]]//​ for a //​[[CL:​Glossary:​function]]//​ of one [[CL:​Glossary:​argument]],​ or **[[CL:​Constant Variable:​nil]]**.
 +  * //entry// - a //​[[CL:​Glossary:​cons]]//​ that is an //​[[CL:​Glossary:​element]]//​ of //alist//, or **[[CL:​Constant Variable:​nil]]**.
 +
 +====Description====
 +**assoc**, **assoc-if**,​ and **assoc-if-not** return the first //​[[CL:​Glossary:​cons]]//​ in //alist// whose //​[[CL:​Glossary:​car]]//​ //​[[CL:​Glossary:​satisfy the test|satisfies the test]]//, or **[[CL:​Constant Variable:​nil]]** if no such //​[[CL:​Glossary:​cons]]//​ is found.
 +                    ​
 +For **assoc**, **assoc-if**,​ and **assoc-if-not**,​ if **[[CL:​Constant Variable:​nil]]** appears in //alist// in place of a pair, it is ignored.
 +
 +====Examples====
 +<​blockquote>​
 +([[CL:​Macros:​defparameter]] *values* '((x . 100) (y . 200) (z . 50))) <​r>​*VALUES*</​r>​
 +(assoc 'y *values*) <r>(Y . 200)</​r>​
 +([[CL:​Functions:​rplacd]] (assoc 'y *values*) 201) <r>(Y . 201)</​r>​
 +(assoc 'y *values*) <r>(Y . 201)</​r>​
 +([[CL:​Macros:​defparameter]] *alist* '((1 . "​one"​)(2 . "​two"​)(3 . "​three"​))) <​r>​*ALIST*</​r>​
 +(assoc 2 *alist*) <r>(2 . "​two"​)</​r>​
 +(assoc-if #'​[[CL:​Functions:​evenp]] *alist*) <r>(2 . "​two"​)</​r>​
 +(assoc-if-not #'​([[CL:​Macros:​lambda]] (x) ([[CL:​Functions:​less|<​]] x 3)) *alist*) <r>(3 . "​three"​)</​r>​
 +([[CL:​Macros:​setf]] *alist* '​(("​one"​ . 1)("​two"​ . 2))) <​r>​(("​one"​ . 1) ("​two"​ . 2))</​r>​
 +(assoc "​one"​ *alist*) <​r>​[[CL:​Constant Variable:​nil|NIL]]</​r>​
 +(assoc "​one"​ *alist* :test #'​[[CL:​Functions:​equalp]]) <​r>​("​one"​ . 1)</​r>​
 +(assoc "​two"​ *alist* :key #'​([[CL:​Macros:​lambda]] (x) ([[CL:​Functions:​char]] x 2))) <​r>​[[CL:​Constant Variable:​nil|NIL]] </r>
 +(assoc #\o *alist* :key #'​([[CL:​Macros:​lambda]] (x) ([[CL:​Functions:​char]] x 2))) <​r>​("​two"​ . 2)</​r>​
 +(assoc 'r '((a . b) (c . d) (r . x) (s . y) (r . z))) <r> (R . X)</​r>​
 +(assoc 'goo '((foo . bar) (zoo . goo))) <​r>​[[CL:​Constant Variable:​nil|NIL]]</​r>​
 +(assoc '2 '((1 a b c) (2 b c d) (-7 x y z))) <r>(2 B C D)</​r>​
 +([[CL:​Macros:​setf]] *alist* '​(("​one"​ . 1) ("​2"​ . 2) ("​three"​ . 3))) <​r>​(("​one"​ . 1) ("​2"​ . 2) ("​three"​ . 3))</​r>​
 +(assoc-if-not #'​[[CL:​Functions:​alpha-char-p]] *alist* :key #'​([[CL:​Macros:​lambda]] (x) ([[CL:​Functions:​char]] x 0))) <​r>​("​2"​ . 2)</​r>​
 +</​blockquote>​
 +
 +
 +====Affected By====
 +None.
 +
 +====Exceptional Situations====
 +Should be prepared to signal an error of type type-error if //alist// is not an //​[[CL:​Glossary:​association list]]//.
 +
 +====See Also====
 +**[[CL:​Functions:​rassoc|Function RASSOC]]**, **[[CL:​Functions:​find|Function FIND]]**, **[[CL:​Functions:​member|Function MEMBER]]**, **[[CL:​Functions:​position|Function POSITION]]**,​ {\secref\TraversalRules}
 +
 +====Example Implementation====
 +To be done.
 +
 +The two expressions
 +
 +<​blockquote>​
 +(assoc //item// //list// :test //fn//)
 +</​blockquote>​
 +
 +and
 +
 +<​blockquote>​
 +([[CL:​Functions:​find]] //item// //list// :test //fn// :key #'​[[CL:​Functions:​car]])
 +</​blockquote>​
 +
 +are equivalent in meaning with one exception: if **[[CL:​Constant Variable:​nil]]** appears in //alist// in place of a pair, and //item// is **[[CL:​Constant Variable:​nil]]**,​ **[[CL:​Functions:​find]]** will compute the //​[[CL:​Glossary:​car]]//​ of the **[[CL:​Constant Variable:​nil]]** in //alist//, find that it is equal to //item//, and return **[[CL:​Constant Variable:​nil]]**,​ whereas **assoc** will ignore the **[[CL:​Constant Variable:​nil]]** in //alist// and continue to search for an actual //​[[CL:​Glossary:​cons]]//​ whose //​[[CL:​Glossary:​car]]//​ is **[[CL:​Constant Variable:​nil]]**.
 +
 +====Notes====
 +The **'':​test-not''​** parameter is deprecated.
 +
 +The //​[[CL:​Glossary:​function]]//​ **assoc-if-not** is deprecated.
 +
 +It is possible to **[[CL:​Functions:​rplacd]]** the result of **assoc**, provided that it is not **[[CL:​Constant Variable:​nil]]**,​ in order to "​update"​ //​alist//​. ​
 +
 +
 +
 +\issue{MAPPING-DESTRUCTIVE-INTERACTION:​EXPLICITLY-VAGUE}
 +\issue{TEST-NOT-IF-NOT:​FLUSH-ALL}
 +\issue{ASSOC-RASSOC-IF-KEY}
 +\issue{ASSOC-RASSOC-IF-KEY:​YES}