Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 具有隐式顺序lisp的平面无序列表和元组_List_Data Structures_Lisp_Common Lisp - Fatal编程技术网

List 具有隐式顺序lisp的平面无序列表和元组

List 具有隐式顺序lisp的平面无序列表和元组,list,data-structures,lisp,common-lisp,List,Data Structures,Lisp,Common Lisp,Lisp中是否有一个函数与assoc处理关联列表的方式相同,但用于平面有序列表和一组具有隐式排序的元组?例如,我有一个平面无序列表和一个查找函数: (defparameter *data2* '((alf age 55 year 2 course lisp) (sue age 22 year 3 course java) (ralf age 16 year 1 course lisp)

Lisp中是否有一个函数与
assoc
处理关联列表的方式相同,但用于平面有序列表和一组具有隐式排序的元组?例如,我有一个平面无序列表和一个查找函数:

(defparameter *data2* '((alf age 55 year 2 course lisp)
                        (sue age 22 year 3 course java)
                        (ralf age 16 year 1 course lisp)
                        (alf age 8 year 2 course lisp)))

(defun lookup (name course data)
  (cdr (assoc name (cdr (assoc course data)))))
这样调用时,
查找
函数类似于:

(lookup 'alf 'course *data*) ==> get lisp
现在,使用“具有隐式顺序的元组”(即,值始终以相同顺序排列的值列表):


对于关联列表,是否有任何函数的工作方式与
assoc
相同,但对于平面无序列表和具有隐式顺序的元组?

我不确定是否完全理解您的意思;像这样的

(defun lookup (name attr data)
  (mapcar (lambda (x) (cadr (member attr x)))
          (remove-if-not (lambda (x) (eq name (car x))) data)))
然后

另一个例子是:

(defun lookup (name attr data)
  (mapcar (lambda (x) (nth attr x))
          (remove-if-not (lambda (x) (eq name (car x))) data)))
然后


不知道我是否完全理解你;像这样的

(defun lookup (name attr data)
  (mapcar (lambda (x) (cadr (member attr x)))
          (remove-if-not (lambda (x) (eq name (car x))) data)))
然后

另一个例子是:

(defun lookup (name attr data)
  (mapcar (lambda (x) (nth attr x))
          (remove-if-not (lambda (x) (eq name (car x))) data)))
然后


这个答案有两个部分。首先,如果您试图访问表单
(key1-value1-key2-value…
)列表中的值,那么应该知道这样的列表有一个特殊的名称;它们被称为属性列表,Common Lisp包含一些用于处理它们的函数。其次,如果您不希望列表中包含键,则可以通过使用
defstruct
:type list
来获得大量所需内容。它将定义使用这些隐式结构所需的必要函数

财产清单 其他一些答案描述了如何做到这一点,并使用了函数
getf
,但没有一个答案明确说明这种结构有一个名称,即:

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

data2变量是一个关联列表,将名称
alf
sue
等映射到属性列表
(年龄55岁2岁…
(年龄22岁3岁…
)等:

(defparameter *data2* '((alf age 55 year 2 course lisp)
                        (sue age 22 year 3 course java)
                        (ralf age 16 year 1 course lisp)
                        (alf age 8 year 2 course lisp)
                        ))
你想去哪里

(lookup 'alf 'course *data2*)
;=> lisp
您可以使用获取alf的属性列表

(cdr (assoc 'alf *data2*))
;=> (age 55 year 2 course lisp)
然后检索课程:

(getf (cdr (assoc 'alf *data2*)) 'course)
;=> lisp
getf
也可以为列表中没有值的情况提供默认值:

(getf (cdr (assoc 'alf *data2*)) 'favorite-color 'blue)
;=> blue
您还可以将
setf
getf
一起使用:

(setf (getf (cdr (assoc 'alf *data2*)) 'course) 'scheme)
;=> scheme

*data2*
;=> ((alf age 55 year 2 course scheme)
;    (sue age 22 year 3 course java)
;    (ralf age 16 year 1 course lisp)
;    (alf age 8 year 2 course lisp))
注意:由于
*data2*
的值是由
quote
生成的文本,因此修改它的结果在技术上是未定义的。在这种情况下,它可能会起作用,但一般来说,不要修改文字数据

的Defstruct:类型列表
在CommonLisp中,可以使用定义简单的记录类型。默认情况下,这些创建的结构可能具有相当高的内存效率(较低的存储开销和恒定的时隙访问)。但是,您可以将
:type list
选项指定为
defstruct
,以使结构以列表的形式实现。例如:

(defstruct (person (:type list))
  name
  age
  course
  year)
这会自动为您定义许多函数。例如,一个是
makeperson

(make-person :name 'alf
             :age 55
             :year 2
             :course 'lisp)
;=> (alf 55 lisp 2)
(person-age (make-person :name 'alf :age 55 :year 2 :course 'lisp))
;=> 55

(person-year '(alf 55 lisp 2))
;=> 2
其他的是访问器。它们(默认情况下)以结构名称和连字符作为前缀。例如,
person-age
person-year
从一个人那里检索年龄和年份时段的值。这些实际上只是对应列表函数的别名(第二个和第三个),因此它们可以处理具有正确结构的列表,即使它们不是用
make person
创建的:

(make-person :name 'alf
             :age 55
             :year 2
             :course 'lisp)
;=> (alf 55 lisp 2)
(person-age (make-person :name 'alf :age 55 :year 2 :course 'lisp))
;=> 55

(person-year '(alf 55 lisp 2))
;=> 2
现在,您可以使用
find
从您的
*data3*
中按姓名检索一个人(请注意,您将课程和年份的顺序从
*data2*
更改为
*data3*
):

您可以使用
person-*
函数获取值:

(person-year (find 'sue *data3* :key 'person-name))
;=> 3
当然,做一些像

(lookup 'alf 'course *data*)
您需要知道符号
课程
对应于函数
个人课程
。您可以创建一个哈希表或另一个关联或属性列表来跟踪这些内容。另一种有点笨拙的方法是取
课程的符号名,即
“课程”
,将
“PERSON-”
与之连接,并对其进行实习,以获得符号
PERSON-course
,然后您可以
与该人进行函数调用。即:

(defun lookup (name slot-name data)
  (funcall (intern (concatenate 'string "PERSON-" (symbol-name slot-name)))
           (find name data :key 'person-name)))

(lookup 'alf 'course *data3*)
;=> lisp

注意:为了使符号插入更加健壮,我们应该确实确保将符号插入到插入访问者名称的包中,并考虑可读的大小写问题。例如,我们可以执行
(intern(连接'string(symbol name'#:person-)(symbol name slot name))(symbol包'make person))
。(当然,有更好的方法可以获得软件包。)

这个答案有两个部分。首先,如果您试图访问表单
(key1-value1-key2-value…
)列表中的值,那么应该知道这样的列表有一个特殊的名称;它们被称为属性列表,Common Lisp包含一些用于处理它们的函数。其次,如果您不希望列表中包含键,则可以通过使用
defstruct
:type list
来获得大量所需内容。它将定义使用这些隐式结构所需的必要函数

财产清单 其他一些答案描述了如何做到这一点,并使用了函数
getf
,但没有一个答案明确说明这种结构有一个名称,即:

属性列表n。1.包含偶数个元素的列表 是交替的名称(有时称为指示器或键)和val
(defun lookup (name slot-name data)
  (funcall (intern (concatenate 'string "PERSON-" (symbol-name slot-name)))
           (find name data :key 'person-name)))

(lookup 'alf 'course *data3*)
;=> lisp