创建list
(setq load-path-list
'("~/.emacs.d/customs"
"~/.emacs.d/download"
"~/.emacs.d/common"))
目的,把load-path-list加入load-path
写法一(用push,迭代式):
(dolist (path load-path-list) (push path load-path))
写法二(用push,函数式):
(mapcar (lambda (path) (push path load-path)) load-path-list)
写法三(用append):
(setq load-path (append load-path load-path-list))
push是破坏性函数,可以直接修改load-path指向的list。而append对list没有破坏性,所以得用setq从新把append的返回值赋值给load-path
有没有直接把一个list的内容加入到另一个list中,而不产生一个新list的函数?
1 个赞
cireu
2019 年2 月 1 日 04:22
2
nconc
你也搜索一下,虽然Emacs的确用的人少
ELISP> (setq a '(3))
(3)
ELISP> (nconc a '(4))
(3 4)
ELISP> a
(3 4)
https://www.emacswiki.org/emacs/DestructiveOperations
3 个赞
Emacs Lisp Manual 中提到的「破坏性」(Destructively / Destructive)指会修改 List 结构的操作,push 并没有没有破坏性,因为它不会修改任何既有 List 的结构:
(push path load-path)
;; 展开
(setq load-path (cons path load-path))
append 也没有破坏性,因为它虽然必须修改列表的结构,但它事先做了必要的拷贝:
(append list1 list2)
;; 有一些类似于
(nconc (copy-sequence list1) list2)
此外,破坏性不等于 In-place 地修改参数,常常还是要依赖于返回值,所以得用 (setq foo (... foo ...))。
2 个赞
哦,原来push也用的是setq
补充一下,nconc是尾插法,有对应的头插法吗?我也在搜一下去
没有,这几天有个帖子说的就是这个,你翻翻就能看到,我手机就不找链接了
cons是追加一个元素,而不是追加一个列表里的所以元素,cons会把要加入的列表当做一个元素对待
(cons '(a b c) '(1 2 3)) ;; => ((a b c) 1 2 3) 而不是 (a b c 1 2 3)
你每次都回得这么简短 说 话 带 空 格,别人很难完全理解
== 我对空格没意见,我觉得他加空格是为了补全字数,还有你应该在下面回复,这么改我帖子好像是我说的一样 @ldbeth
ldbeth是为了不歪楼才改的,说明一下
1 个赞
我只是来搞笑的
没有幽默感啊
抱歉!
学会无视啊!
另外说明一下,我回的短是因为觉得问题有点简单或是超出了我的能力范围亦或是我觉得意义不大还有就是很有意义想顶一下帖子。
艾特 管理员
歪楼了 还算有情可原的吧
点到为止
就你的这个例子,当然是 append (即写法三)最合适了。` 也行,不过实际用的还是 append:
(let ((lst '(1 2 3))
(temp '(4 5 6)))
`(,@lst ,@temp))
;; => (1 2 3 4 5 6)
;;; 等价于
(let ((lst '(1 2 3))
(temp '(4 5 6)))
(append lst temp))
;; => (1 2 3 4 5 6)
lisp里有没有(或者,为什么似乎没有)如下的标准接口:
(ladd lst ele idx) ;; add ele to lst[idx], in place.
使
(setq lst '(0 1 2))
(ladd lst 'a 0)
lst ;; => (a 0 1 2)
(ladd lst 'z (length lst))
lst ;; => (a 0 1 2 z)
LdBeth
2025 年4 月 13 日 02:22
13
(setf (nthcdr n lst)
(cons elm (nthcdr n lst)))
or
(push elm (nthcdr n lst))
1 个赞
https://zhuanlan.zhihu.com/p/416973218
dash
(-insert-at N X LIST) ,返回将 X 插入 LIST 的第 N 位置得到的表
实现方式为先使用 -split-at 对 LIST 分组,再对分组表 Y 进行: (nconc (car Y) (cons X (cadr Y))) 的操作。这样得到的新表与原表 LIST 共享后半段,也就是共享原表第 N 个元素为表头的表。以下代码可以验证上面说法的正确性
~/.emacs.d $ (setq lst '(0 1 2))
(0 1 2)
~/.emacs.d $ (-insert-at 0 'a lst)
(a 0 1 2)
~/.emacs.d $ (-insert-at (length lst) 'z lst)
(0 1 2 z)
不过这个函数返回的是新表,需要手动赋值一下
理解,可以自己实现。只是比较好奇,为什么lisp不提供这种(也许是)十分基础的操作符?
自己实现是不是需要把Emacs里的c list全换掉?还是从其他别的层次切入?