Lisp 当键是字符串时,我可以使用assoc吗?
我有这样一个数据集:Lisp 当键是字符串时,我可以使用assoc吗?,lisp,common-lisp,Lisp,Common Lisp,我有这样一个数据集:”((“红色”35)(“蓝色”68)…) 当键是字符串时,是否可以使用assoc?在这个简单的测试中,没有任何明显的尝试对我有效: CL-USER> (defparameter ggg (list '("foot" 2) '(bar 5))) GGG CL-USER> ggg (("foot" 2) (BAR 5)) CL-USER> (assoc 'bar ggg) (BAR 5) CL-USER> (assoc "foot" ggg) NIL CL
”((“红色”35)(“蓝色”68)…)
当键是字符串时,是否可以使用assoc
?在这个简单的测试中,没有任何明显的尝试对我有效:
CL-USER> (defparameter ggg (list '("foot" 2) '(bar 5)))
GGG
CL-USER> ggg
(("foot" 2) (BAR 5))
CL-USER> (assoc 'bar ggg)
(BAR 5)
CL-USER> (assoc "foot" ggg)
NIL
CL-USER> (assoc '"foot" ggg)
NIL
CL-USER> (assoc 'foot ggg)
NIL
或
取决于您是否希望比较区分大小写。正如其他人所指出的,您可以使用不同类型的键,如中所述:
? (assoc "foot" ggg :test #'equalp)
("foot" 2)
如果确定列表仅包含字符串,则可以使用特定于类型的函数
string=
(区分大小写)或string equal
(不区分大小写)
但是,这些函数也接受符号以及符号和字符串的混合
因此(assoc“ABC”list:test#'string=)
不仅会找到键“ABC”
,还会找到名称为“ABC”
的任何符号,例如符号:ABC
或cl use:ABC
或mypackage:ABC
用于比较任意两个对象的通用equal
和equalp
函数不具有此行为。与上述两个类似,equal
和equalp
分别区分大小写和不区分大小写。然而,他们也比较其他种类的物体
不同于<代码> String=和
。它们也不考虑具有相同名称的符号:<代码>(均衡器Fo:FoO)-> nIL/COD>。当两个参数都是符号时,(equalp“FOO”'FOO)->nil
和equal
应用与equalp
函数相同的测试eq
equal
和equalp
中的一个
这些函数还允许您的列表具有其他类型的键,如数字equalp
将按值比较数字,因此1和1.0是相同的键,而equal
更紧。这两个函数都递归到列表中。列表(12)
和(12)
是相等的,即使它们不是同一个对象(单独使用),而(12)
和(12.0)
不是相等的,而是相等的(除非你有一个非常奇怪的浮点系统)。此外,向量对象不是通过equal
逐元素进行比较,而是通过equalp
进行比较
即使列表中只有字符串,也最好使用这两个函数。
您不会得到太多(如果有的话)性能方面的好处string=
仍然需要验证参数的类型,以确保它们是受支持的类型,并根据参数的字符串和符号组合进行调度equal
根据多种类型的可能性进行调度,但这可以有效地完成
在Lisp中,习惯性地使用过度特定于类型的函数或不适当地严格相等是一种糟糕的做法
string=
故意使用,但不是为了保存机器循环,而是在必须将符号作为字符串或符号与字符串的混合进行比较的情况下使用。例如,如果您正在实现循环
宏,则可以使用字符串=
来检测循环
子句单词,根据ANSI Common Lisp规范,这些单词根据符号名称被视为等价的。用户可以编写(循环:对于42以下的x…
或(循环mypackage:对于42以下的x…
)。但是(循环“FOR…”)
无效!所以你不能只依靠string=
;您必须验证子句单词是否是符号
请参阅
:TEST
关键字参数。
(assoc "foot" ggg :test #'string=)
? (assoc "foot" ggg :test #'equalp)
("foot" 2)
(setq alist '(("one" . 1)("two" . 2))) => (("one" . 1) ("two" . 2))
(assoc "one" alist) => NIL
(assoc "one" alist :test #'equalp) => ("one" . 1)