【问题标题】:Appending lists with symbol names specified in a list of strings附加具有在字符串列表中指定的符号名称的列表
【发布时间】:2011-12-13 18:49:31
【问题描述】:

这可能很容易,但我似乎无法理解

假设我有 a bd

(setq a '(x y))
(setq b '(p q))
(setq d '("a" "b"))

如何获取包含(x y p q) 的列表以及我对d 的信息

更新; 好的,我尝试过的是这个

(apply 'nconc (mapcar (lambda (x)
               (symbol-value (intern x)))
           d))

但我真的不明白 nconc 是做什么的。如果评估两次,值会发生变化。三次emacs 没有反应

【问题讨论】:

  • C-h f nconc -> nconc 改变最后一个元素。请改用concat
  • @Daimrod concat 返回一个字符串而不是一个列表。
  • nconc 是一种破坏性功能:它不是在不更改旧列表的情况下为您构建新列表,而是修改旧列表以生成新列表。至少下面的一些示例是非破坏性的。
  • (concatenate 'list ...) 只需调用 append 并引入您不需要的其他 Common LISP 内容。根据预期使用appendnconc 会更简单。
  • 除非你知道自己在做什么,否则不要乱用 nconc 或其他修改列表结构的函数。 如果你真的需要修改列表结构(而不​​是创建新列表),你会知道的。炫耀这条指导方针,后果自负——人们很容易认为一切正常,但后来才发现问题,而且往往与真正导致问题的原因相去甚远。

标签: emacs lisp elisp


【解决方案1】:

应该这样做:

(apply 'append (mapcar (lambda (name) (symbol-value (intern name))) d))

你能改变d 使用符号而不是字符串吗?这样做会简单得多:

(setq d '(a b))
(apply 'append (mapcar 'symbol-value d))

如果在您设置d 时知道ab 的内容,您甚至可以这样做:

(setq d `(,@a ,@b))

【讨论】:

  • 这正是我所尝试的。但如果我的列表很大,emacs 似乎无处可去。
  • 这正是您尝试过的,还是您尝试使用nconc 做某事?列表a 和列表b 有多大?
  • 其实我都试过了。我有点明白我做错了什么。感谢您的宝贵时间。
【解决方案2】:

mapcan:

(let ((a '(x y))
      (b '(p q))
      (d '("a" "b")))
  (mapcan (lambda (x) (symbol-value (intern x))) d))

【讨论】:

    【解决方案3】:

    这应该很接近:

    (append (eval (read-from-string (car d))) (eval (read-from-string (cadr d))))
    

    如果 d 可以更长,您可以将 (eval (read-from-string x)) 映射到您的列表,然后将 append 应用于结果;我会把它留作练习:)

    【讨论】:

    • 使用eval 并不是很好的风格,应该像瘟疫一样避免使用,除非你真的知道你需要它。
    【解决方案4】:

    我的 Emacs Lisp foo 不是很强大,但也许你可以尝试以下方法

     (reduce 'append
          (map 'list 
              '(lambda (l) (eval (read l)) ) 
               d ))
    

    这也适用于长列表。

    【讨论】:

    • 和 Scott 一样,你不需要 eval 也不应该使用它。
    猜你喜欢
    • 2021-08-19
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 2021-04-25
    • 2012-09-14
    • 2012-05-23
    相关资源
    最近更新 更多