บทความทั้งหมด

JSON Sort Keys: เหตุใดจึงต้องเรียงลำดับคีย์ของอ็อบเจกต์

ภาษาไทยไม่มีตัวพิมพ์ใหญ่-เล็กให้ปวดหัวเหมือนภาษาละติน แต่กลับมีปัญหาการเรียงลำดับตัวอักษรที่ซับซ้อนกว่ามาก นั่นคือ "สระนำ" ที่เขียนไว้หน้าพยัญชนะแต่ต้องเรียงลำดับราวกับอยู่หลังมัน

เหตุใดจึงต้องเรียงลำดับคีย์

  • การเปรียบเทียบ (diff) หากเอกสาร JSON สองฉบับที่มีข้อมูลเหมือนกันมีลำดับคีย์ต่างกัน diff ข้อความจะแสดงความแตกต่างที่ผิดพลาด การเรียงลำดับช่วยขจัดปัญหานี้
  • ผลลัพธ์ที่แน่นอน หากอ็อบเจกต์เดียวกันถูกซีเรียลไลซ์หลายครั้ง (เช่น เพื่อสร้างแฮชหรือคีย์แคช) คีย์ที่เรียงลำดับแล้วจะรับประกันผลลัพธ์เดียวกันทุกครั้ง
  • ความสามารถในการอ่าน อ็อบเจกต์ที่เรียงตามตัวอักษรจะดูผ่านได้เร็วขึ้นและหาฟิลด์เฉพาะได้ง่ายขึ้น โดยเฉพาะในโครงสร้างขนาดใหญ่

การเรียงลำดับแบบเรียกซ้ำ

เพื่อให้ผลลัพธ์คาดเดาได้ การเรียงลำดับมักถูกนำไปใช้แบบเรียกซ้ำ — ไม่ใช่แค่กับคีย์ระดับบนสุด แต่กับคีย์ของอ็อบเจกต์ที่ซ้อนกันทั้งหมดในทุกระดับความลึก ลำดับขององค์ประกอบในอาร์เรย์จะไม่เปลี่ยนแปลง เนื่องจากสำหรับอาร์เรย์ ลำดับขององค์ประกอบเป็นส่วนที่มีความหมายของข้อมูล

ทำไม "เรียงตามตัวอักษร" ในภาษาไทยไม่ใช่แค่เรียงตาม code point

อักษรไทยมีกลุ่มที่เรียกว่า "สระนำ" (เ, แ, โ, ใ, ไ) ซึ่งเขียนไว้หน้าพยัญชนะต้นของพยางค์ แต่พจนานุกรมไทยกลับเรียงคำเหล่านี้ราวกับสระอยู่หลังพยัญชนะ เช่นคำว่า "เก" ในการเรียงพจนานุกรมจะถูกจัดไว้ในตำแหน่งเดียวกับ "ก" ตามด้วยสระเอ ไม่ใช่เรียงตามลำดับอักขระ Unicode ที่ปรากฏจริงในสตริง หากเรียงคีย์ JSON ภาษาไทยด้วยการเปรียบเทียบ code point ธรรมดา ผลลัพธ์จะไม่ตรงกับลำดับที่คนไทยคุ้นเคยจากพจนานุกรมเลย

เมื่อไม่จำเป็น

หาก JSON ถูกใช้โดยโปรแกรมเท่านั้น (ไม่ใช่มนุษย์หรือเครื่องมือ diff) การเรียงลำดับคีย์มักไม่ให้ประโยชน์เชิงปฏิบัติใด ๆ — parser อ่านอ็อบเจกต์เหมือนกันไม่ว่าลำดับฟิลด์จะเป็นอย่างไร

เรียงแบบไบต์ต่อไบต์ยังคงมีประโยชน์

แม้การเรียงแบบ code point จะไม่ตรงกับลำดับพจนานุกรมไทย แต่สำหรับ diff และผลลัพธ์ที่แน่นอน (deterministic output) มันก็ยังใช้งานได้ดี เพราะเป้าหมายคือให้ผลลัพธ์เดิมซ้ำได้ทุกครั้ง ไม่ใช่ให้มนุษย์อ่านตามลำดับพจนานุกรม — ปัญหาการเรียงแบบ locale-aware จะสำคัญก็ต่อเมื่อผลลัพธ์นั้นถูกแสดงให้คนไทยอ่านโดยตรง เช่น รายการรายชื่อในหน้าเว็บ ไม่ใช่คีย์ภายในไฟล์ config

ลองใช้เครื่องมือ