2567
|
1 ;;; assoc.el --- insert/delete/sort functions on association lists
|
|
2
|
|
3 ;; Author: Barry A. Warsaw <bwarsaw@cen.com>
|
|
4 ;; Keywords: extensions
|
|
5
|
|
6 ;; This software is distributed in the hope that it will be useful,
|
|
7 ;; but WITHOUT ANY WARRANTY. No author or distributor accepts
|
|
8 ;; responsibility to anyone for the consequences of using it or for
|
|
9 ;; whether it serves any particular purpose or works at all, unless he
|
|
10 ;; says so in writing.
|
|
11
|
|
12 ;; This software was written as part of the supercite author's
|
|
13 ;; official duty as an employee of the United States Government and is
|
|
14 ;; thus in the public domain. You are free to use that particular
|
|
15 ;; software as you wish, but WITHOUT ANY WARRANTY WHATSOEVER. It
|
|
16 ;; would be nice, though if when you use any of this code, you give
|
|
17 ;; due credit to the author.
|
|
18
|
|
19 ;;; Commentary:
|
|
20
|
|
21 ;; Association list utilities providing insertion, deletion, sorting
|
|
22 ;; fetching off key-value pairs in association lists.
|
|
23
|
|
24 ;;; Code:
|
|
25
|
|
26 (defun asort (assoc-symbol key)
|
|
27 "Move a specified key-value pair to the head of an alist.
|
|
28 The alist is referenced by ALIST-SYMBOL. Key-value pair to move to
|
|
29 head is one matching KEY. Returns the sorted list and doesn't affect
|
|
30 the order of any other key-value pair. Side effect sets alist to new
|
|
31 sorted list."
|
|
32 (set alist-symbol
|
|
33 (sort (copy-alist (eval alist-symbol))
|
|
34 (function (lambda (a b) (equal (car a) key))))))
|
|
35
|
|
36
|
|
37 (defun aelement (key value)
|
|
38 "Makes a list of a cons cell containing car of KEY and cdr of VALUE.
|
|
39 The returned list is suitable as an element of an alist."
|
|
40 (list (cons key value)))
|
|
41
|
|
42
|
|
43 (defun aheadsym (alist)
|
|
44 "Return the key symbol at the head of ALIST."
|
|
45 (car (car alist)))
|
|
46
|
|
47
|
|
48 (defun anot-head-p (alist key)
|
|
49 "Find out if a specified key-value pair is not at the head of an alist.
|
|
50 The alist to check is specified by ALIST and the key-value pair is the
|
|
51 one matching the supplied KEY. Returns nil if ALIST is nil, or if
|
|
52 key-value pair is at the head of the alist. Returns t if key-value
|
|
53 pair is not at the head of alist. ALIST is not altered."
|
|
54 (not (equal (aheadsym alist) key)))
|
|
55
|
|
56
|
|
57 (defun aput (alist-symbol key &optional value)
|
|
58 "Inserts a key-value pair into an alist.
|
|
59 The alist is referenced by ALIST-SYMBOL. The key-value pair is made
|
|
60 >from KEY and optionally, VALUE. Returns the altered alist or nil if
|
|
61 ALIST is nil.
|
|
62
|
|
63 If the key-value pair referenced by KEY can be found in the alist, and
|
|
64 VALUE is supplied non-nil, then the value of KEY will be set to VALUE.
|
|
65 If VALUE is not supplied, or is nil, the key-value pair will not be
|
|
66 modified, but will be moved to the head of the alist. If the key-value
|
|
67 pair cannot be found in the alist, it will be inserted into the head
|
|
68 of the alist (with value nil if VALUE is nil or not supplied)."
|
|
69 (let ((elem (aelement key value))
|
|
70 alist)
|
|
71 (asort alist-symbol key)
|
|
72 (setq alist (eval alist-symbol))
|
|
73 (cond ((null alist) (set alist-symbol elem))
|
|
74 ((anot-head-p alist key) (set alist-symbol (nconc elem alist)))
|
|
75 (value (setcar alist (car elem)))
|
|
76 (t alist))))
|
|
77
|
|
78
|
|
79 (defun adelete (alist-symbol key)
|
|
80 "Delete a key-value pair from the alist.
|
|
81 Alist is referenced by ALIST-SYMBOL and the key-value pair to remove
|
|
82 is pair matching KEY. Returns the altered alist."
|
|
83 (asort alist-symbol key)
|
|
84 (let ((alist (eval alist-symbol)))
|
|
85 (cond ((null alist) nil)
|
|
86 ((anot-head-p alist key) alist)
|
|
87 (t (set alist-symbol (cdr alist))))))
|
|
88
|
|
89
|
|
90 (defun aget (alist key &optional keynil-p)
|
|
91 "Returns the value in ALIST that is associated with KEY.
|
|
92 Optional KEYNIL-P describes what to do if the value associated with
|
|
93 KEY is nil. If KEYNIL-P is not supplied or is nil, and the value is
|
|
94 nil, then KEY is returned. If KEYNIL-P is non-nil, then nil would be
|
|
95 returned.
|
|
96
|
|
97 If no key-value pair matching KEY could be found in ALIST, or ALIST is
|
|
98 nil then nil is returned. ALIST is not altered."
|
|
99 (let ((copy (copy-alist alist)))
|
|
100 (cond ((null alist) nil)
|
|
101 ((progn (asort 'copy key)
|
|
102 (anot-head-p copy key)) nil)
|
|
103 ((cdr (car copy)))
|
|
104 (keynil-p nil)
|
|
105 ((car (car copy)))
|
|
106 (t nil))))
|
|
107
|
|
108
|
|
109 (defun amake (alist-symbol keylist &optional valuelist)
|
|
110 "Make an association list.
|
|
111 The association list is attached to the alist referenced by
|
|
112 ALIST-SYMBOL. Each element in the KEYLIST becomes a key and is
|
|
113 associated with the value in VALUELIST with the same index. If
|
|
114 VALUELIST is not supplied or is nil, then each key in KEYLIST is
|
|
115 associated with nil.
|
|
116
|
|
117 KEYLIST and VALUELIST should have the same number of elements, but
|
|
118 this isn't enforced. If VALUELIST is smaller than KEYLIST, remaining
|
|
119 keys are associated with nil. If VALUELIST is larger than KEYLIST,
|
|
120 extra values are ignored. Returns the created alist."
|
|
121 (let ((keycar (car keylist))
|
|
122 (keycdr (cdr keylist))
|
|
123 (valcar (car valuelist))
|
|
124 (valcdr (cdr valuelist)))
|
|
125 (cond ((null keycdr)
|
|
126 (aput alist-symbol keycar valcar))
|
|
127 (t
|
|
128 (amake alist-symbol keycdr valcdr)
|
|
129 (aput alist-symbol keycar valcar))))
|
|
130 (eval alist-symbol))
|
|
131
|
|
132 (provide 'assoc)
|
|
133
|
|
134 ;;; assoc.el ends here
|