簡體   English   中英

如何插入到 ELisp 中列表的中間?

[英]How can I insert into the middle of a list in ELisp?

我有以下數據結構作為 ELisp 變量( ispell-tex-skip-alists ):

((("---" ispell-tex-arg-end 2)
  ("---" ispell-tex-arg-end)
  ("---" ispell-tex-arg-end)
  ("---" ispell-tex-arg-end)
  ("---" ispell-tex-arg-end 0)
  ("---" ispell-tex-arg-end)
  ("---" . "---"))
 (("---" ispell-tex-arg-end 0)
  ("---" ispell-tex-arg-end 2)
  ("env1" . "endenv1")
  ("env2" . "endenv2")))

我可以使用cddadr隔離我需要的列表部分,但我需要向此列表添加一個元素:

((("---" ispell-tex-arg-end 2)
  ("---" ispell-tex-arg-end)
  ("---" ispell-tex-arg-end)
  ("---" ispell-tex-arg-end)
  ("---" ispell-tex-arg-end 0)
  ("---" ispell-tex-arg-end)
  ("---" . "---"))
 (("---" ispell-tex-arg-end 0)
  ("---" ispell-tex-arg-end 2)
  ("env1" . "endenv1")
  ("env2" . "endenv2")
  ("env3" . "endenv3")))

我試過add-to-list ,但顯然我需要add-to-listcddadr部分的符號名稱(我可以在技術上優化為cadr )才能使add-to-list工作。

我怎樣才能達到我需要的結果?


最佳嘗試:

(defun LaTeX-ispell-skip-environment (env &optional star)
  (let ((start (concat "%s" (if star "\\*?")))
    (end   (concat "\\\\end[    \n]*{[  \n]*%s" (if star "\\*?") "[     \n]*}")))
    (let ((env-list (cddadr ispell-tex-skip-alists)))
      (setcdr (last env-list)
          (cons (format start env)
            (format end env))))))

我假設您的方法中缺少一個list

(defun LaTeX-ispell-skip-environment (env &optional star)
  (let ((start (concat "%s" (if star "\\*?")))
    (end   (concat "\\\\end[    \n]*{[  \n]*%s" (if star "\\*?") "[     \n]*}")))
    (let ((env-list (cddadr ispell-tex-skip-alists)))
      (setcdr (last env-list)
              (list 
               (cons (format start env)
                     (format end env)))))))

在您的版本中,相關列表的結構發生了變化。 在修改之前,它是一個缺點列表。 修改后是一個混合列表。 大多數條目都是 conses,但最后一個 car 是一個字符串,最后一個 cdr 也是一個字符串。

或者setcdrlast ,您可以使用nconc

(defun LaTeX-ispell-skip-environment (env &optional star)
  (let ((start (concat "%s" (if star "\\*?")))
    (end   (concat "\\\\end[    \n]*{[  \n]*%s" (if star "\\*?") "[     \n]*}")))
    (let ((env-list (cddadr ispell-tex-skip-alists)))
      (nconc env-list
             (list 
              (cons (format start env)
                    (format end env)))))))

測試

接下來是一個測試。 為了與原始發布的想要的結果進行比較,我將"\\\\\\\\end[ \\n]*{[ \\n]*%s"替換為"end%s""[ \\n]*}" ""LaTeX-ispell-skip-environment 在的端progn的結果(LaTeX-ispell-skip-environment "env3")與測試equal針對想要的結果。 測試返回t

(progn
  (defun LaTeX-ispell-skip-environment (env &optional star)
    (let ((start (concat "%s" (if star "\\*?")))
      (end   (concat "end%s" (if star "\\*?") "")))
      (let ((env-list (cddadr ispell-tex-skip-alists)))
    (setcdr (last env-list)
        (list 
         (cons (format start env)
               (format end env)))))))

  (setq ispell-tex-skip-alists
    '((("---" ispell-tex-arg-end 2)
       ("---" ispell-tex-arg-end)
       ("---" ispell-tex-arg-end)
       ("---" ispell-tex-arg-end)
       ("---" ispell-tex-arg-end 0)
       ("---" ispell-tex-arg-end)
       ("---" . "---"))
      (("---" ispell-tex-arg-end 0)
       ("---" ispell-tex-arg-end 2)
       ("env1" . "endenv1")
       ("env2" . "endenv2"))))

  (LaTeX-ispell-skip-environment "env3")

  (equal ispell-tex-skip-alists
     '((("---" ispell-tex-arg-end 2)
        ("---" ispell-tex-arg-end)
        ("---" ispell-tex-arg-end)
        ("---" ispell-tex-arg-end)
        ("---" ispell-tex-arg-end 0)
        ("---" ispell-tex-arg-end)
        ("---" . "---"))
       (("---" ispell-tex-arg-end 0)
        ("---" ispell-tex-arg-end 2)
        ("env1" . "endenv1")
        ("env2" . "endenv2")
        ("env3" . "endenv3")))))

為了更籠統地回答標題中提到的問題,這里有一個函數,它在列表的第 n 個位置插入一個元素:

(defun insert-into-list (list el n)
  "Insert into list LIST an element EL at index N.

If N is 0, EL is inserted before the first element.

The resulting list is returned.  As the list contents is mutated
in-place, the old list reference does not remain valid."
  (let* ((padded-list (cons nil list))
         (c (nthcdr n padded-list)))
    (setcdr c (cons el (cdr c)))
    (cdr padded-list)))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM