我有一个通过嵌套 cons
生成的列表,该列表创建了这样的结构 - 我在下面创建了一个示例列表。
(define lst '(((name . test) . 15) ))
我希望稍后使用 assq
过滤名称,然后访问每个名称的值。例如,在上面的示例中,我希望能够做一些时尚的事情(伪代码):
if (cdr (assq 'name lst2) == test, print the value [15]
我该怎么做?我只能执行 (assq 'name (car (lst)))
来取回正确的名称,但随后我无法访问值 15
答案 0 :(得分:1)
您需要编写自己的类似 assoc
的过程。要么有一个关键功能来提取你想要比较的东西,要么有一个通用的测试功能可以做到这一点,或者两者兼而有之。这是允许通用测试功能的一个:
(define (asst o l test)
;; test is called on o and the element of l in that order
(if (null? l)
#f
(let ((f (car l))
(r (cdr l)))
(if (test o f)
f
(asst o r test)))))
现在
> (asst 'name '(((name . test) . 15))
(lambda (o el)
(eqv? o (car (car el)))))
'((name . test) . 15)
如果您想对列表进行更一般的测试,那么有一个名为 find
的通用函数可以执行此操作。 find
is defined in SRFI 1,但很容易实现:
(define (find pred? l)
(cond
((null? l)
#f)
((pred? (first l))
(first l))
(else
(find pred? (rest l)))))
给定 find
然后很容易编写一个函数来查找例如结构中的特定键和值:
(define (findfv l field value)
(find (λ (e)
(and (eqv? (car (car e)) field)
(eqv? (cdr (car e)) value)))
l))
现在
> (findfv '(((name . fred) . 12) ((feature . legs) 8) ((name . josephine) . 15)) 'name 'josephine)
'((name . josephine) . 15)
> (findfv '(((name . fred) . 12) ((feature . legs) 8) ((name . josephine) . 15)) 'feature 'legs)
'((feature . legs) 8)
(在 CL 中提供的 assoc
函数允许测试和关键选项)