วิธีการต่อสองรายการเข้าด้วยกัน?


15

ขออภัย elisp ไม่ใช่ของฉันที่ดีที่สุด ฉันต้องการรวมสองรายการของสตริงด้วยวิธีนี้:

("a" "b" "c") + ("d" "e" "f") -> ("a" "b" "c" "d" "e" "f")

ลำดับไม่สำคัญดังนั้นฉันจึงเขียนรหัสนี้:

(while lista
  (add-to-list 'listb (car lista)) 
  (setq lista (cdr lista)))

มันใช้งานได้ แต่ฉันสงสัยว่ามีฟังก์ชั่นที่ทำสิ่งนี้แล้ว

เบาะแสใด ๆ ขอบคุณล่วงหน้า.


4
ดูรายการสิ่งปลูกสร้างของคู่มือ Elisp
Drew

2
appendเป็นคำตอบที่ถูกต้องที่นี่ แต่อีก (ทำลาย) (setcdr (last a) b)วิธีการทำก็จะเป็น
ฌอน Allred

1
กำลังทำงานกับรายการหรือไม่ dash.el ! (-concat '(1) '(2 3) '(4)) ;; => '(1 2 3 4)
Ehvince

อย่าใช้add-to-listในรหัส Lisp (มันบอกว่าสิ่งนี้ใน docstring) pushแต่การใช้งาน
Radon Rosborough

คำตอบ:


25

นอกจากนี้คุณยังสามารถใช้ผนวก

(append '("a" "b" "c") '("d" "e" "f"))

2
และ(nconc '("a" "b" "c") '("d" "e" "f"))
ฏหมาย

1
อ๋อใช่แน่นอนappendดูเหมือนว่าจะดีกว่าที่นี่
JeanPierre

nconc ใช้งานได้ แต่ถ้าคุณเก็บรายการไว้ในตัวแปรพวกมันจะถูกแก้ไขโดย nconc เช่น (ให้ ((a '(1 2 3)) (b' (3 4 5))) (nconc ab) a) จะแก้ไขตัวแปร
John Kitchin

1
FYI cl-concatenateใช้appendเมื่อ TYPE คือlistคำตอบทั้งคู่จึงให้ผลลัพธ์เหมือนกัน
phils

ใช่มันทำงานได้อย่างแน่นอน ขอบคุณทุกคนมากสำหรับความช่วยเหลือของคุณ
Daniele

3

concatenate เป็นชื่อแทนสำหรับ 'cl-concatenate' ใน 'cl.el'

(เรียงลำดับประเภทเรียงต่อกัน ... )

เชื่อมต่อกันเป็นลำดับประเภท TYPE อาร์กิวเมนต์ SEQUENCE

ดังนั้นสำหรับตัวอย่างของคุณ

(concatenate 'list '("a" "b" "c") '("d" "e" "f"))

เนื่องจากมันถูกกำหนดไว้ในclคุณอาจต้อง(require 'cl)ก่อนมิฉะนั้นคุณสามารถใช้cl-concatenateซึ่งดูเหมือนว่าจะโหลดตามค่าเริ่มต้น

นอกจากนี้ตามที่ระบุโดย @phils cl-concatenateเพียงแค่เรียกใช้appendเมื่อเป็น TYPE 'listนี่คือแหล่งที่มาจากcl-extra.el:

(defun cl-concatenate (type &rest sequences)
  "Concatenate, into a sequence of type TYPE, the argument SEQUENCEs.
\n(fn TYPE SEQUENCE...)"
  (pcase type
    (`vector (apply #'vconcat sequences))
    (`string (apply #'concat sequences))
    (`list (apply #'append (append sequences '(nil))))
    (_ (error "Not a sequence type name: %S" type))))

ดังนั้นหากคุณใช้รายการเท่านั้นมันง่ายกว่าที่จะใช้โดยตรงappendตามที่ระบุไว้โดย @John Kitchin

ในที่สุด @lawlist พูดถึงnconc:

nconc เป็นฟังก์ชั่นในตัวใน 'ซอร์สโค้ด C'

(nconc & rest LISTS)

เชื่อมต่อรายการจำนวนเท่าใดก็ได้ด้วยการแก้ไข เฉพาะอาร์กิวเมนต์สุดท้ายเท่านั้นที่ไม่มีการเปลี่ยนแปลงและไม่จำเป็นต้องเป็นรายการ

นี่แปลว่าอะไร:

(nconc '("a" "b" "c") '("d" "e" "f"))
=> ("a" "b" "c" "d" "e" "f")

(setq l1 '("a" "b" "c")
      l2 '("d" "e" "f"))
(nconc l1 l2)
=> ("a" "b" "c" "d" "e" "f")
l1
=> ("a" "b" "c" "d" "e" "f")
l2
=> ("d" "e" "f")

ขอบคุณ แต่ดูเหมือนว่าจะส่งคืนข้อผิดพลาดหากอาร์กิวเมนต์ที่ 2 และ 3 เป็นตัวแปรและไม่ใช่รายการที่ชัดเจน
Daniele

1
(setq l1 '("a" "b" "c") l2 '("d" "e" "f")) (concatenate 'list l1 l2)ทำงานได้ดี
JeanPierre

@Daniele ฉันสงสัยว่าคุณกำลังพยายามอ้างอิงตัวแปรซึ่งหมายความว่าพวกเขาไม่ได้รับการประเมินค่ารายการของพวกเขา (เช่นคุณต้องการvarnameมากกว่า'varname)
phils

เพื่อความสมบูรณ์ฉันอาจพูดถึงวิธีที่ไม่เกี่ยวข้องกับ CL ในการเรียงลำดับของประเภทใด ๆ ใน Emacs> = 25: seq-concatenate(หลังจาก(require 'seq)) แม้ว่าสิ่งนี้จะเป็นเพียงการตัดcl-concatenateคำ
โหระพา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.