- ผู้เขียนพยายามเรียง ไฟล์รูปภาพ ตามลำดับตัวอักษร แต่พบว่า ผลการเรียงของระบบปฏิบัติการและตัวจัดการไฟล์ไม่เหมือนกัน
- ใน Linux
ls จะเรียงได้ตามปกติ แต่ตัวจัดการไฟล์แบบ GUI ส่วนใหญ่ เช่น Windows, Google Drive, KDE Dolphin ใช้ “natural sort” ที่ตีความชื่อไฟล์ซึ่งมีตัวเลขแบบ ตามค่าตัวเลขจริง
- จึงเกิดผลลัพธ์ที่ต่างจากการเรียงสตริงแบบดั้งเดิม เช่น
file-10.txt มาอยู่ก่อน file-9.txt
- สาเหตุที่แท้จริงคือโทรศัพท์สองเครื่องใช้รูปแบบการตั้งชื่อไฟล์ต่างกัน โดยเครื่องหนึ่ง ต่อมิลลิวินาทีไว้หลังวินาทีทันที แต่อีกเครื่อง คั่นด้วยขีดล่าง ทำให้เกณฑ์การเรียงต่างกัน
- สุดท้าย วิธีแก้มีเพียง ทำรูปแบบชื่อไฟล์ให้เป็นมาตรฐานเดียวกัน หรือปรับค่าที่ซ่อนอยู่ของตัวจัดการไฟล์แต่ละตัว และผู้เขียนเสียดาย “ยุคที่คอมพิวเตอร์เดาความต้องการของผู้ใช้น้อยกว่าการทำตามคำสั่ง”
พื้นหลังและสถานการณ์ของปัญหา
- ผู้เขียนไปเดินเขากับพ่อ และถ่ายรูปด้วยโทรศัพท์ Android ของแต่ละคน ก่อนจะนำรูปทั้งหมดมาเก็บไว้ในโฟลเดอร์เดียว
- รูปแบบชื่อไฟล์ภาพคือ
IMG_YYYYMMDD_HHmmss หรือมีตัวเลขเพิ่มเติมต่อท้ายก่อน .jpg
- เพราะชื่อไฟล์นี้เรียงตามปี เดือน วัน และเวลาอยู่แล้ว จึงคิดว่าหากเรียงไฟล์ ตามตัวอักษร ก็จะได้ลำดับตามเวลาที่ถ่าย
- แต่เมื่อใช้ Windows PC, Google Drive, KDE Dolphin ฯลฯ กลับพบว่า ไฟล์ที่ใช้รูปแบบเดียวกันไม่ได้เรียงต่อกันตามลำดับ
- ตัวอย่าง: รูปที่พ่อถ่ายเวลา 5:54 กลับมาอยู่ก่อนรูปเวลา 9:20 และไปอยู่หลังรูปเวลา 12:11 เป็นต้น ทำให้ลำดับเพี้ยน
- Gnome และตัวจัดการไฟล์อื่นบนสมาร์ตโฟนก็ให้ผลแบบเดียวกัน
- ขณะที่คำสั่ง Linux
ls กลับรักษาลำดับได้ถูกต้อง จึงยิ่งทำให้งง
การวิเคราะห์สาเหตุ
- ตอนแรกผู้เขียนคิดว่าโทรศัพท์สักเครื่องอาจใช้ อักขระแปลกแทนขีดล่าง (_) แต่เมื่อตรวจด้วยคำสั่ง Linux
ls ก็พบว่าเรียงได้ปกติ
- บน Linux distribution หลายตัวและแม้แต่เซิร์ฟเวอร์ OpenBSD นั้น
ls เรียงตามตัวอักษรได้ถูกต้อง
- ตรงกันข้าม ตัวจัดการไฟล์แบบ GUI จำนวนมาก (Windows, Google Drive, KDE Dolphin ฯลฯ) จะเปรียบเทียบ ค่าตัวเลขจริง เมื่อชื่อไฟล์มีตัวเลข
- กล่าวคือใช้ natural sorting แทนการเรียงตามตัวอักษร เป็นค่าเริ่มต้น
- Natural sort จะเปรียบเทียบตัวเลขในสตริงตาม ค่าตัวเลข ไม่ใช่ตามค่าของตัวอักษรธรรมดา
- ตัวอย่าง:
file-9.txt < file-10.txt → เป็นลำดับที่คนส่วนใหญ่คาดหวัง
- แต่การเรียงแบบดั้งเดิมจะมองว่า
1 < 9 จึงทำให้ file-10.txt มาก่อน
- อย่างไรก็ตาม ตัวจัดการไฟล์สมัยนี้เมื่อเจอ “ส่วนที่เป็นตัวเลข” ก็มัก ตีความส่วนนั้นเป็นค่าตัวเลขจริงและบังคับให้ 9 มาก่อน 10
- ซึ่งอาจไม่ตรงกับลำดับที่ผู้ตั้งชื่อไฟล์ตั้งใจไว้
สาเหตุจริงของปัญหาและวิธีแก้
- โทรศัพท์ของพ่อใส่ตัวเลขมิลลิวินาทีต่อท้ายวินาทีทันที ส่วนโทรศัพท์ของผู้เขียน คั่นไว้ด้วยขีดล่าง
- โทรศัพท์พ่อ: ต่อมิลลิวินาทีหลังวินาทีทันที → ตัวเลขก้อนนั้นใหญ่ขึ้นและถูกเลื่อนไปท้ายกว่า
- โทรศัพท์ผู้เขียน: คั่นด้วยขีดล่าง → ถูกมองเป็นอีกสตริงหนึ่ง
- วิธีแก้คือ จัดชื่อไฟล์ของฝั่งใดฝั่งหนึ่งใหม่ให้เป็นรูปแบบเดียวกันอย่างสม่ำเสมอ
- ใน KDE Dolphin สามารถเลือกให้เรียงตามตัวอักษรล้วนได้จากตัวเลือกในโปรแกรม แต่การตั้งค่านี้ซ่อนอยู่จึงใช้งานลำบาก
- และเนื่องจากแต่ละโปรแกรมรองรับไม่เหมือนกัน อาจต้องตั้งค่าแยกกันทุกครั้ง
บทสรุปของผู้เขียน
- แม้จะสั่งให้เรียง “ตามตัวอักษร” แต่ผู้เขียนวิจารณ์ว่า ซอฟต์แวร์กลับเดาเจตนาของผู้ใช้แล้วใช้วิธีเรียงแบบอื่น
- เขาคิดถึงวิธีการแบบในอดีต ที่ คอมพิวเตอร์ทำงานตามคำสั่งตรง ๆ อย่างเรียบง่าย
1 ความคิดเห็น
ความเห็นจาก Hacker News
คิดว่าวิธีการจัดเรียงที่ Microsoft, Google และ KDE เลือกใช้นั้นเข้าใจได้ง่ายกว่าและครอบคลุมกรณีใช้งานที่พบบ่อยกว่า โดยมองว่าสถานการณ์ของผู้เขียนเป็นกรณีที่พบได้น้อยมาก คนส่วนใหญ่มักอยากให้ “10” มาอยู่ถัดจาก “9” มากกว่า เดสก์ท็อปเอนวายรอนเมนต์ก็ระบุการจัดเรียงว่าเป็น “ตามชื่อ” ไม่ใช่ “ตามตัวอักษร” จึงไม่ได้ทำให้เข้าใจผิด แม้จะไม่ชอบที่คอมพิวเตอร์พยายามเดาเจตนา แต่เหมือนฟีเจอร์อย่างบันทึกอัตโนมัติ มันก็มีประโยชน์ในชีวิตจริง ถ้ามีตัวเลือกจัดเรียงตามตัวอักษรจริง ๆ ก็คงดี แต่ค่าเริ่มต้นควรเป็นแบบที่ตรงกับกรณีทั่วไปและใช้งานได้อย่างเป็นธรรมชาติ
หัวข้อนี้ทำให้นึกถึงข้อถกเถียงเรื่อง “Worse is better” วิธีจัดเรียงแบบง่ายตาม ANSI/Unicode ที่ผู้เขียนต้องการ จริง ๆ แล้วอาจเป็นฟีเจอร์ที่มีแต่นักพัฒนาเพียงส่วนน้อยเท่านั้นที่ต้องการ ในทางปฏิบัติผู้ใช้ GUI 99% อยากได้การจัดเรียงที่เป็นธรรมชาติมากกว่า การรู้ว่าใครคือผู้ใช้หลักส่งผลต่อการออกแบบผลิตภัณฑ์อย่างมาก ฟีเจอร์ที่ดีกว่าอาจเหมาะกับตัวผลิตภัณฑ์ แต่สำหรับระบบแล้ว ความเรียบง่ายอาจเหมาะกับการเติบโตและวิวัฒนาการมากกว่า
เวลาไปหาไฟล์ที่ตั้งชื่อเป็นค่าแฮช การจัดเรียงอัตโนมัตินี่แหละที่น่ารำคาญที่สุด บน Windows นี่เป็นหนึ่งในไม่กี่ตัวเลือกที่ฉันรีบปิดผ่าน registry เลย บ่อยครั้งก็คิดถึงยุคที่คอมพิวเตอร์ทำแค่ตามที่สั่ง ทุกวันนี้มันไม่ใช่แค่อ่านใจผู้ใช้ แต่เหมือนพยายามจะเปลี่ยนวิธีคิดของผู้ใช้ด้วย เลยไม่ชอบใจ และไม่พอใจกับทัศนคติแบบเผด็จการที่ว่า “ผู้ใช้ผิด” ไม่ว่าจะในซอฟต์แวร์โอเพนซอร์สด้วยหรือไม่ก็ตาม
ทุกคนชอบอ้างว่าตัวเองรู้ความต้องการของผู้ใช้ทั่วไป แต่ทำไมกลับไม่มีใครเสนอให้คอมพิวเตอร์เปลี่ยนชื่อไฟล์ให้เองตามใจเลย ถ้าจะไม่ยึดการเรียงแบบ ASCII ก็ไม่เห็นจำเป็นต้องยึดชื่อไฟล์ที่รวมส่วนขยายไว้ด้วย จริง ๆ แล้วผู้ใช้ไม่ได้สนใจนามสกุลอย่าง jpg หรือ png และก็ไม่ได้แยกแยะตัวพิมพ์ใหญ่-เล็กด้วย บนตระกูล Windows เองก็ใช้ส่วนขยายมานานเพราะเหตุผลด้านความเข้ากันได้เก่า ๆ เป็นหลัก น่าแปลกที่บังคับให้ใช้ “ชื่อไฟล์แบบคอมพิวเตอร์” แต่กลับยืนกรานจะทำลายแค่ “การจัดเรียงแบบคอมพิวเตอร์” ผู้ใช้ต้องการอะไรนั้นไม่มีใครรู้แน่ จึงไม่ควรฟันธง
สำหรับฉัน ส่วนใหญ่แล้วการจัดเรียงแบบอิงเวอร์ชันที่บทความนี้อธิบายดีกว่ามาก ถึงขั้นที่การแสดงผลแบบเรียงตามตัวอักษรดูเหมือนบั๊กเสียด้วยซ้ำ ปัญหาไม่ใช่แนวคิดเรื่องการเรียง แต่เป็นเรื่องการติดป้ายเรียกมากกว่า
sortของ Linux ตอนนี้ก็รองรับการเรียงแบบเวอร์ชัน (sort -V) แล้ว แม้จะไม่รู้รายละเอียดภายใน แต่มันทำงานได้ดีในสถานการณ์ส่วนใหญ่ และที่สำคัญคือเปิดหรือปิดได้ง่ายมากสิ่งที่ถูกสั่งไม่ใช่ให้จัดเรียงไฟล์ “ตามตัวอักษร” แต่เป็น “ตามชื่อ” ดังนั้นการตีความจึงต่างกันได้ในแต่ละ OS คิดว่าส่วนใหญ่เลือกรูปแบบที่เหมาะกับผู้ใช้มากกว่าโดยอิงตามเหตุผลและข้อมูล อนาคตอาจเพิ่มกฎอย่างเช่นถ้ากลุ่มตัวเลขมี 0 นำหน้าก็ให้ใช้การเรียงตามตัวอักษรแบบเดิม หรืออาจมีตัวเลือกให้ผู้ใช้เลือกเอง
ใน macOS Foundation มี
NSString.localizedStandardCompare()ให้ใช้อย่างเป็นทางการสำหรับการจัดเรียงใน Finder ส่วน Windows ก็มีStrCompareLogicalนั่นคือแต่ละแพลตฟอร์มกำลังกำหนดเกณฑ์ของการเรียงตามชื่อ หรือก็คือ natural sort อย่างเป็นทางการlsและตอนนี้ก็เริ่มคิดว่าวิธีนี้ดีกว่า แอปรูปภาพก็มักเรียงตาม timestamp อยู่แล้ว และถ้าจำเป็นต้องเรียงไฟล์ตามชื่อจริง ๆ ก็คงเลือกเรียงตามวันที่สร้างหรือไม่ก็ normalize ชื่อไฟล์เองไปเลยรายงานของ Unicode พูดไว้อย่างชัดเจนว่าการจัดเรียงเปลี่ยนไปตามภาษาและบริบท เช่น ถ้าเรียง “A-10” แบบตัวอักษรโดยไม่ตีความตัวเลข “A-10” จะมาก่อน “A-2” แม้จะซับซ้อน แต่คิดว่านี่แหละคือเหตุผลที่ file browser เลือกใช้ natural sort
การเรียงให้ “foo9” มาก่อน “foo10” นี่แหละคือ “natural sort” ไม่นานมานี้เพิ่งได้รู้วิธีทำ natural sort ด้วยโค้ด Python แค่ 2 บรรทัด แล้วพอใจมาก ขอแนะนำ โค้ดบน Stack Overflow ที่เกี่ยวข้อง
sort(1)ก็รองรับ natural sort (-V) เหมือนกัน สร้างไฟล์รูปภาพขึ้นมาแล้วใช้ls | sort -Vก็จะเรียงได้ถูกต้อง และผลลัพธ์du -sh *ก็สามารถใช้ตัวเลือกsort -hเพื่อเรียงได้ด้วยไม่ได้โหยหาการเรียงแบบที่ทำให้ “Image-1.jpg, Image-11.jpg, Image-2.jpg” ปะปนกันเลย แม้จะเคยรู้สึกแปลกกับ natural sort อยู่บ้าง แต่พอ Windows เปลี่ยนมาเรียงตามค่าตัวเลขจริงก็สะดวกขึ้นมาก ไฟล์ถูกเรียงอย่างเป็นธรรมชาติและน่าพอใจมาก