ฉันมักพบว่าตัวเองใช้รายการขี้เกียจเมื่อฉันต้องการเวกเตอร์และในทางกลับกัน นอกจากนี้บางครั้งฉันก็มีเวกเตอร์ของแผนที่เมื่อฉันต้องการชุดแผนที่จริงๆ มีฟังก์ชั่นตัวช่วยที่จะช่วยฉันในการแปลงระหว่างประเภทเหล่านี้หรือไม่?
ฉันมักพบว่าตัวเองใช้รายการขี้เกียจเมื่อฉันต้องการเวกเตอร์และในทางกลับกัน นอกจากนี้บางครั้งฉันก็มีเวกเตอร์ของแผนที่เมื่อฉันต้องการชุดแผนที่จริงๆ มีฟังก์ชั่นตัวช่วยที่จะช่วยฉันในการแปลงระหว่างประเภทเหล่านี้หรือไม่?
คำตอบ:
อย่าลืมว่าของเก่าที่เชื่อถือได้into
ช่วยให้คุณสามารถนำอะไรก็ได้seq
(list, vector, map, set, sorted-map) และคอนเทนเนอร์ว่างเปล่าที่คุณต้องการเติมแล้วใส่into
ลงไป
(into [] '(1 2 3 4)) ==> [1 2 3 4] "have a lazy list and want a vector"
(into #{} [1 2 3 4]) ==> #{1 2 3 4} "have a vector and want a set"
(into {} #{[1 2] [3 4]}) ==> {3 4, 1 2} "have a set of vectors want a map"
(into #{} [{1 2} {3 4}]) ==> #{{1 2} {3 4}} "have a vector of maps want a set of maps"
into
เป็นกระดาษห่อหุ้มconj
ซึ่งเป็นนามธรรมพื้นฐานสำหรับการแทรกรายการใหม่ลงในคอลเล็กชันอย่างเหมาะสมตามประเภทของคอลเล็กชัน หลักการที่ทำให้การไหลนี้เพื่อให้เป็นอย่างดีก็คือว่าเป็น Clojure สร้างตามแนวคิด composableในกรณีนี้into
ที่ด้านบนของด้านบนของคอลเลกชันและconj
seq
ตัวอย่างข้างต้นจะยังคงเรียบเรียงได้ดีหากผู้รับถูกส่งต่อในเวลาดำเนินการ: เนื่องจาก abstractions พื้นฐาน ( seq
และconj
) ถูกนำไปใช้กับคอลเลกชันทั้งหมด (และคอลเลกชันของ Java จำนวนมากด้วย) ดังนั้นสิ่งที่เป็นนามธรรมที่สูงกว่าก็ไม่จำเป็นต้องกังวล เกี่ยวกับกรณีพิเศษที่เกี่ยวข้องกับข้อมูลจำนวนมาก
into
ใช้conj
การทำ(into '() some-seq)
จะทำให้ได้รายการที่ตรงกันข้ามกับบางส่วนเนื่องจากconj
สอดคล้องกับรายการ
into
ใช้ช่วงเวลาชั่วคราว (สำหรับประเภท seq ส่วนใหญ่) เพื่อให้ได้ลักษณะการทำงานที่ดีกว่าวิธีการแปลงอื่น ๆ ส่วนใหญ่
vec
, set
และโดยทั่วไปจะinto
เป็นเพื่อนของคุณได้อย่างง่ายดาย "แปลง" ประเภทคอลเลกชันอื่น
คุณต้องการเปลี่ยนเวกเตอร์ของแผนที่เป็นแผนที่ของแผนที่อย่างไร? คุณต้องการคีย์คุณสามารถใช้กับอินพุตตัวอย่าง / เอาต์พุตที่คาดหวังได้หรือไม่?
สำหรับเวกเตอร์มีvec
ฟังก์ชัน
user=> (vec '(1 2 3))
[1 2 3]
สำหรับลำดับที่ขี้เกียจมีไฟล์ lazy-seq
ฟังก์ชั่น
user=> (lazy-seq [1 2 3])
(1 2 3)
สำหรับการแปลงเป็นเซตมีset
ฟังก์ชัน
user=> (set [{:a :b, :c :d} {:a :b} {:a :b}])
#{{:a :b} {:a :b, :c :d}}
lazy-seq
แทนที่จะseq
เพิ่มทิศทางที่ไร้ประโยชน์ จริงๆถ้าคุณต้องการที่จะกลับมาบางสิ่งบางอย่างที่ไม่ใช่ศูนย์แม้ก่อนล้าง collectiosn thene sequence
มี lazy-seq
เป็นโครงสร้างระดับต่ำ
อีกหนึ่งคำตอบสำหรับการแปลงจากรายการเป็นแผนที่ (เพื่อความสมบูรณ์) - จากที่นี่ :
(apply hash-map '(1 2 3 4))
;=>{1 2, 3 4}
ในการแปลงเวกเตอร์เป็นรายการคุณสามารถใช้for
ดังนี้:
=> (for [i [1 2 3 4]] i)
(1 2 3 4)
เมื่อคุณไม่ต้องการจัดการข้อมูลให้ใช้seq
กับเวกเตอร์:
=> (seq [1 2 3])
(1 2 3)
for
คุณจะทำได้(map identity [1 2 3 4])
ไม่จำเป็นต้องแปลงเวกเตอร์เป็นรายการ Clojure จะปฏิบัติต่อเวกเตอร์เหมือนกับที่จะปฏิบัติต่อรายการ - เป็นลำดับ - เมื่อต้องใช้ลำดับ ตัวอย่างเช่น,
user=> (cons 0 [1 2 3])
(0 1 2 3)
หากคุณต้องการตรวจสอบให้แน่ใจว่าเวกเตอร์ได้รับการปฏิบัติตามลำดับให้รวมไว้ในseq
:
user=> (conj [1 2 3] 0) ; treated as a vector
[1 2 3 0]
user=> (conj (seq [1 2 3]) 0) ; treated as a sequence
(0 1 2 3)
หากคุณมีเวกเตอร์ของแผนที่และคุณต้องการชุดแผนที่ก็ไม่สำคัญว่าเวกเตอร์นั้นจะมีแผนที่ คุณเพียงแค่แปลงเวกเตอร์เป็นชุดตามปกติ:
user=> (set [{:a 1, :b 2} {"three" 3, "four" 4}])
#{{:a 1, :b 2} {"four" 4, "three" 3}}