我可以使用关联列表中的“get”功能吗?

时间:2013-12-21 13:22:08

标签: lisp common-lisp

我有以下代码:

(setq months '((january 1) (february 2) ...))

我可以使用get将此列表用作地图(使用键和值)

喜欢:

(get 'months 'january)

得到结果:1

是否可以在Lisp中执行此操作而无需显式设置如下属性:

(setf (get 'months 'january) 1)
(setf (get 'months 'february) 2)
...

如果在Common Lisp中无法做到这一点,是否可以使用Lisp的任何其他方言?

2 个答案:

答案 0 :(得分:5)

没有。 documentation for get表示用法是

  

获取符号指示符&可选默认值=>值

     

在属性的符号属性列表中找到属性   指标与指标相同,并返回其对应的指标   适当的价值。如果有多个属性1具有该属性   指标,获得使用第一个这样的属性。如果没有财产   使用该属性指示符,返回默认值。

property list定义为:

  

属性列表1.包含偶数个元素的列表   是交替的名称(有时称为指标或键)和值   (有时称为属性)。当有多个名字时   在属性列表中具有相同名称的值对,第一个这样   对确定属性。 2.(符号)的组成部分   包含属性列表的符号。

您的数据采用association list

的形式
  

协会名单代表一个关联的一个conses列表   带有值的键,每个缺点的汽车是键,而cdr是   与该键相关联的值。

因此,您可以使用assoc访问其中的值。您可以使用属性列表,在这种情况下,如果它不是符号的属性列表,则使用getf,如果是get(如上所述),则使用CL-USER> (defparameter *months-alist* '((january . 1) (february . 2) (march . 3))) *MONTHS-ALIST* CL-USER> (cdr (assoc 'february *months-alist*)) 2 符号的属性列表。以下是所有三种方法的示例。

关联列表

CL-USER> (defparameter *months-plist*
           '(january 1 february 2 march 3))
*MONTHS-PLIST*
CL-USER> (getf *months-plist* 'march)
3

财产清单

CL-USER> (setf (get '*months* 'january) 1
               (get '*months* 'february) 2
               (get '*months* 'march) 3)
3
CL-USER> (get '*months* 'january)
1

符号的属性列表(不常见)

CL-USER> (defparameter *months-hash* (make-hash-table :test 'eq))
*MONTHS-HASH*
CL-USER> (setf (gethash 'january *months-hash*) 1
               (gethash 'february *months-hash*) 2
               (gethash 'march *months-hash*) 3)
3
CL-USER> (gethash 'february *months-hash*)
2 ; the value
T ; it was present in the table

其他方式

当然,您也可以使用哈希映射,或者在订购内容的数据的情况下,您可以找到元素的位置:

哈希表

CL-USER> (defparameter *months-sequence* 
           #(january february march april may june july august september))
*MONTHS-SEQUENCE*
CL-USER> (1+ (position 'april *months-sequence*))
4

位置

{{1}}

答案 1 :(得分:-1)

您正在使用a-list作为数据结构来实现关联映射。它具有 O(n)复杂度(线性),因此对于大型地图来说不是一个好的结构。

Common Lisp有一个包含容器的丰富库,可以看到hyperspec,特别是hash-tables。它们可能更相关。如果您认为它们很短(例如使用ASSOC Common Lisp函数),您仍然可以使用a-lists。您还可以考虑B-trees ...