0
|
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 ;;; Synched up with: FSF 19.30.
|
|
20
|
|
21 ;;; Commentary:
|
|
22
|
|
23 ;; Association list utilities providing insertion, deletion, sorting
|
|
24 ;; fetching off key-value pairs in association lists.
|
|
25
|
|
26 ;;; Code:
|
|
27
|
|
28 (defun asort (alist-symbol key)
|
|
29 "Move a specified key-value pair to the head of an alist.
|
|
30 The alist is referenced by ALIST-SYMBOL. Key-value pair to move to
|
|
31 head is one matching KEY. Returns the sorted list and doesn't affect
|
|
32 the order of any other key-value pair. Side effect sets alist to new
|
|
33 sorted list."
|
|
34 (set alist-symbol
|
|
35 (sort (copy-alist (eval alist-symbol))
|
|
36 (function (lambda (a b) (equal (car a) key))))))
|
|
37
|
|
38
|
|
39 (defun aelement (key value)
|
|
40 "Makes a list of a cons cell containing car of KEY and cdr of VALUE.
|
|
41 The returned list is suitable as an element of an alist."
|
|
42 (list (cons key value)))
|
|
43
|
|
44
|
|
45 (defun aheadsym (alist)
|
|
46 "Return the key symbol at the head of ALIST."
|
|
47 (car (car alist)))
|
|
48
|
|
49
|
|
50 (defun anot-head-p (alist key)
|
|
51 "Find out if a specified key-value pair is not at the head of an alist.
|
|
52 The alist to check is specified by ALIST and the key-value pair is the
|
|
53 one matching the supplied KEY. Returns nil if ALIST is nil, or if
|
|
54 key-value pair is at the head of the alist. Returns t if key-value
|
|
55 pair is not at the head of alist. ALIST is not altered."
|
|
56 (not (equal (aheadsym alist) key)))
|
|
57
|
|
58
|
|
59 (defun aput (alist-symbol key &optional value)
|
|
60 "Inserts a key-value pair into an alist.
|
|
61 The alist is referenced by ALIST-SYMBOL. The key-value pair is made
|
|
62 from KEY and optionally, VALUE. Returns the altered alist or nil if
|
|
63 ALIST is nil.
|
|
64
|
|
65 If the key-value pair referenced by KEY can be found in the alist, and
|
|
66 VALUE is supplied non-nil, then the value of KEY will be set to VALUE.
|
|
67 If VALUE is not supplied, or is nil, the key-value pair will not be
|
|
68 modified, but will be moved to the head of the alist. If the key-value
|
|
69 pair cannot be found in the alist, it will be inserted into the head
|
|
70 of the alist (with value nil if VALUE is nil or not supplied)."
|
|
71 (let ((elem (aelement key value))
|
|
72 alist)
|
|
73 (asort alist-symbol key)
|
|
74 (setq alist (eval alist-symbol))
|
|
75 (cond ((null alist) (set alist-symbol elem))
|
|
76 ((anot-head-p alist key) (set alist-symbol (nconc elem alist)))
|
|
77 (value (setcar alist (car elem)))
|
|
78 (t alist))))
|
|
79
|
|
80
|
|
81 (defun adelete (alist-symbol key)
|
|
82 "Delete a key-value pair from the alist.
|
|
83 Alist is referenced by ALIST-SYMBOL and the key-value pair to remove
|
|
84 is pair matching KEY. Returns the altered alist."
|
|
85 (asort alist-symbol key)
|
|
86 (let ((alist (eval alist-symbol)))
|
|
87 (cond ((null alist) nil)
|
|
88 ((anot-head-p alist key) alist)
|
|
89 (t (set alist-symbol (cdr alist))))))
|
|
90
|
|
91
|
|
92 (defun aget (alist key &optional keynil-p)
|
|
93 "Returns the value in ALIST that is associated with KEY.
|
|
94 Optional KEYNIL-P describes what to do if the value associated with
|
|
95 KEY is nil. If KEYNIL-P is not supplied or is nil, and the value is
|
|
96 nil, then KEY is returned. If KEYNIL-P is non-nil, then nil would be
|
|
97 returned.
|
|
98
|
|
99 If no key-value pair matching KEY could be found in ALIST, or ALIST is
|
|
100 nil then nil is returned. ALIST is not altered."
|
|
101 (let ((copy (copy-alist alist)))
|
|
102 (cond ((null alist) nil)
|
|
103 ((progn (asort 'copy key)
|
|
104 (anot-head-p copy key)) nil)
|
|
105 ((cdr (car copy)))
|
|
106 (keynil-p nil)
|
|
107 ((car (car copy)))
|
|
108 (t nil))))
|
|
109
|
|
110
|
|
111 (defun amake (alist-symbol keylist &optional valuelist)
|
|
112 "Make an association list.
|
|
113 The association list is attached to the alist referenced by
|
|
114 ALIST-SYMBOL. Each element in the KEYLIST becomes a key and is
|
|
115 associated with the value in VALUELIST with the same index. If
|
|
116 VALUELIST is not supplied or is nil, then each key in KEYLIST is
|
|
117 associated with nil.
|
|
118
|
|
119 KEYLIST and VALUELIST should have the same number of elements, but
|
|
120 this isn't enforced. If VALUELIST is smaller than KEYLIST, remaining
|
|
121 keys are associated with nil. If VALUELIST is larger than KEYLIST,
|
|
122 extra values are ignored. Returns the created alist."
|
|
123 (let ((keycar (car keylist))
|
|
124 (keycdr (cdr keylist))
|
|
125 (valcar (car valuelist))
|
|
126 (valcdr (cdr valuelist)))
|
|
127 (cond ((null keycdr)
|
|
128 (aput alist-symbol keycar valcar))
|
|
129 (t
|
|
130 (amake alist-symbol keycdr valcdr)
|
|
131 (aput alist-symbol keycar valcar))))
|
|
132 (eval alist-symbol))
|
|
133
|
|
134 (provide 'assoc)
|
|
135
|
|
136 ;;; assoc.el ends here
|