Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 1997

[Clojure] ว่าด้วยเรื่องของ Vector และ List

$
0
0

หลังจากที่ทำความรู้จักกับภาษา 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 ตัวอย่างกัน [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="1.txt"] แต่ตัวภาษาก็มี function ชื่อว่า vector มาใช้สำหรับสร้าง Vector ให้ด้วย ซึ่งน่าจะช่วยเพิ่มทางเลือกให้ใช้งานอีกด้วย แต่ส่วนใหญ่จะใช้แบบแรกกันนะ [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="2.txt"] มาดู function อื่น ๆ สำหรับทำงานกับ Vector กันบ้าง
  • count สำหรับนำจำนวน item ใน Vector
  • first สำหรับดึงค่าในตำแหน่งแรกของ Vector
  • rest จะแสดงข้อมูลตั้งแต่ในลำดับที่สองเป็นต้นไป แต่ return ออกมาไม่ใช่ Vector นะ แต่มันคือ sequence ?
Sequence มันคืออะไร ? ชีวิตยากอะแล้ว พักไว้ก่อน
มาดูตัวอย่างการใช้งาน [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="3.txt"] ถ้าต้องการเข้าถึงข้อมูลแต่ละตำแหน่งละ ? ในภาษา Clojure จะมี function ชื่อว่า nth ให้ใช้งาน โดยจะเริ่มตำแน่งที่ 0 ของ Vector ใช้งานดังนี้ [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="4.txt"] nth มันคืออะไรนะ ? ชื่อมันแปลกดี ไม่เคยพบเห็นมาก่อน ดังนั้นจึงลองไปค้นหาดู พบว่ามันคือ คำที่มีความหมายทางคณิตศาสตร์ ดังนี้ [code] 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" [/code] ถ้าต้องการเพิ่มข้อมูลเข้าไปยัง Vector ทำอย่างไร ? จะใช้ function ชื่อว่า conj ซึ่งย่อมาจาก conjunction หรือการเชื่อมต่อหรือเชื่อมโยง ซึ่งจะทำการเพิ่มข้อมูลไปยังตำแหน่งสุดท้ายของ Vector แต่ถ้าต้องการเพิ่มข้อมูลไปยังตำแหน่งแรกสุดของ Vector สามารถใช้ function cons ซึ่งย่อมาจาก construct มาดูตัวอย่างการใช้งาน [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="5.txt"] สิ่งที่แตกต่างระหว่าง 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
ดังนี้ [gist id="8f6fd3d70a858cc0f3db0cec3178e738" file="6.txt"]

มีคำถามว่า ทำไมต้องมีทั้ง 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 ซึ่งไว้ต้องศึกษาเพิ่มเติมอีก

Viewing all articles
Browse latest Browse all 1997

Trending Articles