Emacs - 如何用let-bound变量替换列表的第n个元素

law*_*ist 3 emacs elisp

我还没有找到如何任何例子更换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- 这是一个漫长的三步过程(即,在开始时逐个添加每个元素).

要解决这两个问题,我在寻找一些帮助,请更换17th的元素the-list(这是字母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)
  ))
Run Code Online (Sandbox Code Playgroud)

列表

'(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)
Run Code Online (Sandbox Code Playgroud)

nth ELEMENT - CHEAT SHEET/LEGEND

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
Run Code Online (Sandbox Code Playgroud)

sds*_*sds 11

你需要使用setcarnthcdr:

(setcar (nthcdr 17 the-list) my-variable)
Run Code Online (Sandbox Code Playgroud)

更常见的类似于lisp的方法是使用广义变量:

(setf (nth 17 the-list) my-variable)
Run Code Online (Sandbox Code Playgroud)


lun*_*orn 5

Emacs有一个广义变量的概念,它基本上允许你改变任意存储位置setf.举例来说,你可以改变carcdr列表的地方,包括car用返回nth.因此,以下代码

(let ((foo 10)
      (l '(1 2 3 4 5 6 7 8)))
  (setf (nth 4 l) foo)
  l)
Run Code Online (Sandbox Code Playgroud)

将返回列表(1 2 3 4 10 6 7 8).

要将变量直接放入带引号的列表中,您必须更改引用的类型.该标准报价'禁止任何评价引用的表达式中.

然而,特殊的Backquote允许您在引用的表达式中计算表达式:

(let* ((foo 10)
      (l `(1 2 3 4 5 ,foo 7 foo)))
  l)
Run Code Online (Sandbox Code Playgroud)

前导逗号标记后续表达式以进行评估,而没有前导逗号的表达式将按字面意思进行.在上面的例子中,foo列表中的第一次出现将被评估,因此替换为10,而第二次出现在列表中字面上结束.

  • 非常感谢您帮助我理解为什么我在尝试使用列表中的变量时遇到很多麻烦。您提供的课程将来会派上用场!:) (2认同)