Могу ли я использовать assoc, когда ключи являются строками?
у меня есть такой набор данных:'(("red" 3 5)("blue" 6 8)...)
можно использовать 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
4 ответов
если вы уверены, что ваш список содержит только строки, вы можете использовать тип функции string= (с учетом регистра) или string-equal (без учета регистра).
однако эти функции также принимают символы и смеси символов и строк.
(assoc "ABC" list :test #'string=) найдет не только ключ "ABC", но и любой символ, которого зовут "ABC", например, символ :abc или cl-use:abc или mypackage:abc.
универсальный equal и equalp функции для сравнение любых двух объектов не имеет такого поведения. Как и вышеупомянутые два, equal и equalp, соответственно, чувствительны к регистру и нечувствительны. Однако они также сравнивают другие виды объектов.
в отличие от string= и string-equal, equal и equalp не считайте строки и символы эквивалентными, то есть (equalp "FOO" 'FOO) -> nil. Они также не считают эквивалентными символы, имеющие одно и то же имя: (equalp 'foo :foo) -> nil. Когда оба аргумента являются символами equal и equalp применить тот же Тест, что и
(assoc "foot" ggg :test #'string-equal)
или
(assoc "foot" ggg :test #'string=)
в зависимости от того, хотите ли вы сравнение с учетом регистра.
Как уже указывали другие, вы можете использовать различные типы ключей, как описано в HyperSpec:
(setq alist '(("one" . 1)("two" . 2))) => (("one" . 1) ("two" . 2))
(assoc "one" alist) => NIL
(assoc "one" alist :test #'equalp) => ("one" . 1)