常见的Lisp:KEY参数使用 [英] Common lisp :KEY parameter use
问题描述
Common Lisp附带的某些功能中包含:KEY
参数.我发现的所有描述都无济于事,并且:KEY
很难在搜索引擎中进行搜索,因为通常会忽略:".
The :KEY
parameter is included in some functions that ship with Common Lisp. All of the descriptions that I have found of them are unhelpful, and :KEY
is difficult to search in a search engine because the ":" is usually ignored.
例如,如何在允许同时使用:TEST
和:KEY
的member
函数中使用它?
How would it be used, for example, in the member
function which allows both :TEST
and :KEY
?
推荐答案
想象一下我们有一个城市列表:
Imagine that we have a list of cities:
(defparameter *cities*
; City Population Area km^2
'((Paris 2265886 105.4)
(Mislata 43756 2.06)
(Macau 643100 30.3)
(Kallithea 100050 4.75)
(Nea-Smyrni 73090 3.52)
(Howrah 1072161 51.74)))
现在我们可以计算人口密度,单位为人/km ^ 2
Now we can compute the population density in people/km^2
(defun city-density (city)
"the density is the population number divided by the area"
(/ (second city) (third city)))
现在,我们要计算人口密度低于21000人/公里^ 2的所有城市的列表.
Now we want to compute a list of all cities which have a density less than 21000 people/km^2.
我们从列表中删除了所有较大的文件,并提供了:test-not
函数.我们需要提供一个匿名函数来进行测试并计算要比较的城市的密度.
We remove all larger ones from the list and are providing a :test-not
function. We need to provide an anonymous function which does the test and computes the density of the city to compare.
CL-USER 85 > (remove 21000 *cities*
:test-not (lambda (a b)
(>= a (city-density b))))
((NEA-SMYRNI 73090 3.52) (HOWRAH 1072161 51.74))
我们可以通过提供数字:test-not
函数>=
并使用city-density
函数作为键来计算每个提供的城市的价值,从而简化不使用匿名函数的情况:
We can write it simpler without the anonymous function by providing the numeric :test-not
function >=
and use the city-density
function as the key to compute the value from each provided cities:
CL-USER 86 > (remove 21000 *cities* :test-not #'>= :key #'city-density)
((NEA-SMYRNI 73090 3.52) (HOWRAH 1072161 51.74))
因此,既具有测试谓词又具有键函数,可以更轻松地提供用于序列计算的构件...
So having both a test predicate and a key function makes it easier to provide the building blocks for sequence computations...
现在想象我们使用CLOS和城市CLOS对象的列表:
Now imagine that we use CLOS and a list of city CLOS objects:
(defclass city ()
((name :initarg :name :reader city-name)
(population :initarg :population :reader city-population)
(area :initarg :area :reader city-area)))
(defparameter *city-objects*
(loop for (name population area) in *cities*
collect (make-instance 'city
:name name
:population population
:area area)))
(defmethod density ((c city))
(with-slots (population area)
c
(/ population area)))
现在,我们按上述方式计算列表:
Now we compute the list as above:
CL-USER 100 > (remove 21000 *city-objects* :test-not #'>= :key #'density)
(#<CITY 42D020DDFB> #<CITY 42D020DF23>)
CL-USER 101 > (mapcar #'city-name *)
(NEA-SMYRNI HOWRAH)
如果我们将密度作为带有吸气剂的插槽,则可以执行以下操作:
If we have the density as a slot with a getter, we can do this:
(defclass city ()
((name :initarg :name :reader city-name)
(population :initarg :population :reader city-population)
(area :initarg :area :reader city-area)
(density :reader city-density)))
(defmethod initialize-instance :after ((c city) &key)
(with-slots (density)
c
(setf density (density c))))
(defparameter *city-objects*
(loop for (name population area) in *cities*
collect (make-instance 'city
:name name
:population population
:area area)))
现在我们按上述方法计算列表,但是 key 是 density 插槽的吸气剂:
Now we compute the list as above, but the key is the getter of the density slot:
CL-USER 102 > (remove 21000 *city-objects* :test-not #'>= :key #'city-density)
(#<CITY 42D026D7EB> #<CITY 42D026D913>)
CL-USER 103 > (mapcar #'city-name *)
(NEA-SMYRNI HOWRAH)
这篇关于常见的Lisp:KEY参数使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!