หลังจากที่ทำความรู้จักกับภาษา Clojure ไปบ้างเล็กน้อยแล้ว
ต่อมาก็เริ่มไปดู Data structure พื้นฐาน
ทั้ง Vector, List, Map, Keyword และ Set
โดยครั้งนี้จะเรียนรู้กับ Vector และ List กัน
มาเริ่มกันเลย

Vector เป็น data structure ที่ใช้เยอะมาก ๆ ในภาษา Clojure

ซึ่งในแต่ละ item นั้นมีชนิดที่แตกต่างกันได้
รวมทั้งสามารถมี Vector ซ้อน Vector ได้แบบสบาย ๆ
โดยที่รูปแบบ syntax ของ Vector นั้น
จะอยู่ในเครื่องหมายก้ามปู []
แต่ละ item คั่นด้วยช่องว่าง (space bar)
สามารถใส่ comma (,) ได้นะ แต่ตัว compiler จะ ignore ไปเอง
มาดู code ตัวอย่างกัน

แต่ตัวภาษาก็มี function ชื่อว่า vector มาใช้สำหรับสร้าง Vector ให้ด้วย
ซึ่งน่าจะช่วยเพิ่มทางเลือกให้ใช้งานอีกด้วย
แต่ส่วนใหญ่จะใช้แบบแรกกันนะ

มาดู function อื่น ๆ สำหรับทำงานกับ Vector กันบ้าง

  • count สำหรับนำจำนวน item ใน Vector
  • first สำหรับดึงค่าในตำแหน่งแรกของ Vector
  • rest จะแสดงข้อมูลตั้งแต่ในลำดับที่สองเป็นต้นไป แต่ return ออกมาไม่ใช่ Vector นะ แต่มันคือ sequence ?

Sequence มันคืออะไร ?
ชีวิตยากอะแล้ว
พักไว้ก่อน

มาดูตัวอย่างการใช้งาน

ถ้าต้องการเข้าถึงข้อมูลแต่ละตำแหน่งละ ?
ในภาษา Clojure จะมี function ชื่อว่า nth ให้ใช้งาน
โดยจะเริ่มตำแน่งที่ 0 ของ Vector ใช้งานดังนี้

nth มันคืออะไรนะ ?
ชื่อมันแปลกดี ไม่เคยพบเห็นมาก่อน
ดังนั้นจึงลองไปค้นหาดู
พบว่ามันคือ คำที่มีความหมายทางคณิตศาสตร์ ดังนี้

nth
enTH/Submit
adjective MATHEMATICS
denoting an unspecified member of a series of numbers or enumerated items.
"systematic sampling by taking every nth name from the list"

ถ้าต้องการเพิ่มข้อมูลเข้าไปยัง Vector ทำอย่างไร ?
จะใช้ function ชื่อว่า conj ซึ่งย่อมาจาก conjunction หรือการเชื่อมต่อหรือเชื่อมโยง
ซึ่งจะทำการเพิ่มข้อมูลไปยังตำแหน่งสุดท้ายของ Vector

แต่ถ้าต้องการเพิ่มข้อมูลไปยังตำแหน่งแรกสุดของ Vector
สามารถใช้ function cons ซึ่งย่อมาจาก construct
มาดูตัวอย่างการใช้งาน

สิ่งที่แตกต่างระหว่าง conj และ cons คือ
cons จะทำการ return ข้อมูลเป็นชนิด sequence อีกแล้วนะ !!

ปล.
สิ่งที่ควรจำไว้คือ
ทุก ๆ function ที่กระทำกับ Vector นั้น
จะไม่ไปแก้ไขหรือเปลี่ยนแปลง Vector ต้นฉบับเลย
เพียงแค่ return value กลับมาเท่านั้น
ซึ่งเป็นพื้นฐานของภาษา Clojure นั่นคือ immutability

มาดู List กันบ้าง ว่าเป็นอย่างไร ?

มันเหมือนกับ Vector มาก ๆ
แต่การใช้งานมีรูปแบบที่ต่างกัน
มาดูการสร้าง List กัน
โดยใช้เครื่องหมายวงเล็บ และ execute list ด้วยเครื่องหมาย single qoute (‘)
หรือใช้ function ชื่อ list ก็ได้
ส่วน function อื่น ๆ ใช้เหมือน Vector เลยครับ
ไม่ต้อมาจำให้วุ่นวาย

แต่สิ่งที่ต่างคือ function conj และ cons ให้ผลเหมือนกัน !!
คือเป็นการเพิ่มไปยังตำแหน่งแรกของ List

ดังนี้

มีคำถามว่า ทำไมต้องมีทั้ง Vector และ List ด้วยละ ทั้ง ๆ ที่เหมือนกันมาก ๆ ?

สิ่งที่ Clojure อธิบายไว้อย่างน่าสนใจคือ
มองจากภายนอกนั้นจะเหมือนกันมาก (External)
แต่เมื่อดูการทำงานภายในแล้วต่างกัน (Internal)

โดยที่ Vector นั้นมองเหมือนกับ array
ข้อมูลแต่ละตำแหน่งอยู่ในหน่วยความจำที่ต่อเนื่องกันดังรูป

แต่ List จะตรงข้ามกับ Vector เลย เพราะว่าคือ Linked List
แสดงดังรูป


ส่งผลให้การเข้าถึงข้อมูลในแต่ละตำแหน่งต่างกัน
โดยการเข้าถึงของ Vector จะเร็วกว่า List
เพราะว่าใช้การคำนวณทางคณิตศาสตร์
ส่วน List ต้องไปตามลำดับที่ link กันไว้
แต่การใช้งานต้อดู use case ด้วยว่าอะไรที่เหมาะกับ Vector หรือ List

สิ่งที่ Clojure ให้ความสำคัญมาก ๆ ของ data structure ต่าง ๆ คือ
เรื่องของ performance ในการทำงาน

ซึ่งในโลกของ Clojure นั้น
จะมีการใช้งาน Vector มากกว่า List มาก

ปล. การทำงานภายในของ Vector และ List น่าสนใจมาก
มีทั้งเรื่องของ caching และ การจัดการ memory
ซึ่งไว้ต้องศึกษาเพิ่มเติมอีก

Tags: