我没有找到任何示例来替换列表的nth
元素,而无需首先用函数add-to-ordered-list
添加每个元素(一个接一个( - 例如,(add-to-ordered-list 'the-list 'a 1)
。 这需要随后删除元素 - 例如,(delq a the-list)
。 该过程的第三步是添加新元素 - 例如,(add-to-ordered-list 'the-list "HELLO-WORLD!" 1)
。 由于以下名为 variable-list-example
的函数使用 26 个元素,因此我正在寻找一种更好的方法,而不是首先添加所有 26 个元素(一个接一个(来基本上为每个元素分配一个位置编号。 该函数add-to-ordered-list
使用的数字赋值与标准nth
元素方法不同一位数,其中第一个元素的值为 0
,而add-to-ordered-list
对第一个元素使用1
的值。 以下是add-to-ordered-list
文档的链接: http://www.gnu.org/software/emacs/manual/html_node/elisp/List-Variables.html
此外,在列表开头使用组合'(
似乎可以防止在列表中使用 let-bound 变量 - 例如,let bound变量在列表中显示为my-variable
而不是HELLO-WORLD!
。 我发现的唯一解决方法是上面提到的使用 add-to-ordered-list
的示例——这是一个漫长的三步过程(即,在开始时逐个添加每个元素(。
为了解决这两个问题,我正在寻找一些帮助,请将the-list
的17th
元素(即字母 r
(替换为my-variable
(HELLO-WORLD!
(。
(defun variable-list-example ()
(interactive)
(let* (
(my-variable "HELLO-WORLD!")
(the-list '(a b c d e f g h i j k l m n o p q r s t u v w x y z)))
;; replace the 17th element of `the-list` with `my-variable`
(message "Presto -- this is your new list: %s" the-list)
))
目录
'(a b c d e f g h i j k l m n o p q r s t u v w x y z)
第 N 个元素 -- 备忘单/图例
element 0: a
element 1: b
element 2: c
element 3: d
element 4: e
element 5: f
element 6: g
element 7: h
element 8: i
element 9: j
element 10: k
element 11: l
element 12: m
element 13: n
element 14: o
element 15: p
element 16: q
element 17: r
element 18: s
element 19: t
element 20: u
element 21: v
element 22: w
element 23: x
element 24: y
element 25: z
你需要使用 setcar
和 nthcdr
:
(setcar (nthcdr 17 the-list) my-variable)
更常见的类似 Lisp 的方法是使用广义变量:
(setf (nth 17 the-list) my-variable)
Emacs 有一个广义变量的概念,它本质上是允许你用 setf
来改变任意的存储位置。 例如,您可以更改列表的位置car
和cdr
位置,包括 nth
返回的car
。 因此,以下代码
(let ((foo 10)
(l '(1 2 3 4 5 6 7 8)))
(setf (nth 4 l) foo)
l)
将返回列表(1 2 3 4 10 6 7 8)
。
要将变量直接放入带引号的列表中,必须更改引号的类型。 标准引号'
禁止引用表达式内的任何计算。
但是,特殊的反引号允许您计算带引号的表达式内的表达式:
(let* ((foo 10)
(l `(1 2 3 4 5 ,foo 7 foo)))
l)
前导逗号标记后续表达式以供评估,而不带前导逗号的表达式将按字面意思获取。 在上面的示例中,将评估列表中第一次出现的foo
,因此替换为10
,而第二次出现最终出现在列表中。
添加一个专门关于add-to-ordered-list
的后期答案,因为我认为人们对它的作用和工作方式存在混淆。
add-to-ordered-list
允许您为单个列表元素指定(记录(特定顺序。
但该列表也可以包含没有为其记录特定顺序的元素。 这些元素始终放在列表的末尾,在所有具有特定记录顺序的元素之后。
如果要替换具有记录顺序的元素,则需要将其从列表中删除并添加其替换(这是您猜测的(。
(add-to-ordered-list 'the-list 'a 1) ; Records order 1 for element (symbol) a.
(delq a the-list) ; Removes a from the list.
(add-to-ordered-list 'the-list 'HELLO 1) ; Records order 1 for element (symbol) HELLO.
要补充一些内容,以帮助澄清一点:
您不能使用字符串元素,例如
"HELLO"
,因为记录元素的顺序要求它们可以使用eq
(而不是equal
或string=
(进行区分。您可以从元素中删除记录的顺序,而不是从列表中删除该元素。 如果这样做,该元素将保留在列表中,但在具有记录订单的任何元素之后移动。 这不是你想要的(你想替换它(,但要知道这是可能的。 为此,您可以使用元素调用
add-to-ordered-list
,但没有ORDERED
值(或nil
值(。为元素记录的订单不需要为所有元素指定(见上文(,也不必是连续的。 重要的是它们可以在数字上进行比较,因此它们的元素可以排序。 例如,您可以添加元素
a
、b
和c' to an empty list, recording orders of 13, 42, and 6 for them, respectively. The result is the list
(c a b(',因为 6 <12 <42。您甚至可以为多个列表元素记录相同的顺序,在这种情况下,这些元素在列表中是连续的,但它们之间的顺序并不重要。 您可以将记录的订单视为桶或分数。 得分为 3 的所有元素都显示在列表中,然后出现在得分为 7 的所有元素之前,得分为 3(或 7(的元素是连续的。
另请参阅此 emacs.SE 问题。