การจัดเรียงข้อมูลในอาเรย์ ในภาษา JavaScript

5 October 2020

อาเรย์เก็บข้อมูลในรูปแบบของชุดลำดับ และในการทำงานกับอาเรย์เราอาจต้องการเรียงค่าในอาเรย์จากน้อยไปมากหรือจากมากไปน้อย ในภาษา JavaScript นั้นมีสองเมธอดสำหรับเรียงข้อมูลในอาเรย์ และนี่เป็นเนื้อหาที่คุณจะได้เรียนรู้ในบทเรียนนี้

  • การเรียงข้อมูลด้วยเมธอด sort
  • การใช้ฟังก์ชัน Callback ของเมธอด sort
  • การใช้งานเมธอด reverse

การเรียงข้อมูลด้วยเมธอด sort

ในการทำงานกับอาเรย์การเรียงข้อมูลในอาเรย์เป็นการทำงานพื้นฐานที่เราจะต้องเจอ ในกรณีที่เราต้องการเรียงข้อมูลในอาเรย์ ในภาษา JavaScript เราสามารถใช้เมธอด sort ได้ นี่เป็นตัวอย่าง

sorting_array.js
let numbers = [30, 10, 50, 40, 20];
numbers.sort();
console.log("Sorted:", numbers);

let names = ["Chris", "Metin", "John", "Brendan", "Mateo"];
names.sort();
console.log("Sorted:", names);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Sorted: [ 'Brendan', 'Chris', 'John', 'Mateo', 'Metin' ]
Sorted: [ 10, 20, 30, 40, 50 ]

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

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

reverse_array.js
let numbers = [30, 10, 50, 40, 20];
numbers.sort();
console.log("Sorted asc:", numbers);

let sortedDesc = numbers.reverse();
console.log("Sorted desc:", numbers);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Sorted asc: [ 10, 20, 30, 40, 50 ]
Sorted desc: [ 50, 40, 30, 20, 10 ]

เมธอด reverse ทำการกลับลำดับของสมาชิกในอาเรย์ สมาชิกตัวสุดท้ายมาอยู่ในตำแหน่งแรก และสมาชิกตัวแรกจะไปอยู่ที่ตำแหน่งสุดท้ายแทน ดังนั้นถ้าเรามีอาเรย์ที่จัดเรียงจากน้อยไปมากแล้ว การเรียกใช้เมธอด reverse จะได้ทำให้ได้อาเรย์ที่เรียงจากมากไปน้อยนั่นเอง

การทำงานของเมธอด sort นั้นทำการเปลี่ยนแปลงค่าในอาเรย์ปัจจุบัน นั่นหมายความว่าเราจะสูญเสียลำดับเดิมก่อนการจัดเรียง ในกรณีที่ต้องการรักษาลำดับเดิมของอาเรย์เอาไว้ เราสามารถทำการคัดลอกอาเรย์ก่อนการจัดเรียงได้ ยกตัวอย่างเช่น

preverse_order.js
let chars = ["B", "E", "A", "F", "C", "D"];
let copy = chars.slice();
copy.sort();
console.log("Sorted:", copy);
console.log("Original:", chars);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Sorted: [ 'A', 'B', 'C', 'D', 'E', 'F' ]
Original: [ 'B', 'E', 'A', 'F', 'C', 'D' ]

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

การใช้ฟังก์ชัน Callback ของเมธอด sort

การทำงานเริ่มต้นของเมธอด sort นั้นข้อมูลจะถูกจัดเรียงจากน้อยไปมาก และอย่างที่คุณเห็นถ้าหากเราต้องการเรียงจากมากไปน้อย เราสามารถใช้ร่วมกับเมธอด reverse แต่นั่นไม่สามารถแก้ได้ในทุกกรณี เช่น เมื่อค่าในอาเรย์เป็นออบเจ็คและเราต้องการเรียงด้วย Property ของมัน

ดังนั้นในการใช้งานเมธอด sort เราสามารถส่งพารามิเตอร์เป็นฟังก์ชัน Callback เพื่อกำหนดวิธีการเรียงข้อมูลในอาเรย์แบบกำหนดเองได้ นี่เป็นรูปแบบการใช้งาน

arr.sort([compareFunction])

ฟังก์ชัน Callback รับพารามิเตอร์สองตัว a และ b ซึ่งเป็นค่าในอาเรย์ และเราต้องสร้างเงื่อนไขและส่งค่ากลับเป็นหนึ่งในสามค่าต่อไปนี้

  • -1: ทำการสลับตำแหน่งของ a และ b ในกรณที่ a อยู่ทางด้านขวาของ b
  • 1: ทำการสลับตำแหน่งของ a และ b ในกรณที่ a อยู่ทางด้านซ้ายของ b
  • 0: ไม่มีการสลับตำแหน่ง ทั้งสองค่าอยู่ที่ตำแหน่งเดิม

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

sort_ascending.js
let numbers = [30, 10, 50, 40, 20];
numbers.sort(function (a, b) {
    if (a < b)
        return -1;
    else if (a > b)
        return 1;
    else
        return 0;
});
console.log("Sorted:", numbers);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม ซึ่งได้ผลลัพธ์เหมือนในตัวอย่างก่อนหน้า ในความเป็นจริง แล้วเมื่อเราไม่ส่งฟังก์ชัน Callback เมธอด sort จะเรียงอาเรย์ด้วยวิธีนี้

Sorted: [ 10, 20, 30, 40, 50 ]

ต่อไปจะเป็นการอธิบายการทำงานของตัวอย่างนี้ว่าในแต่ละขั้นตอนนั้นทำงานอย่างไร

ในการทำงาน เมธอด sort จะวนค่าในอาเรย์ด้วยอัลกอรึมทึมของการจัดเรียง และส่งค่าสมาชิกในอาเรย์ a และ b มาเพื่อให้เราสร้างเงื่อนไข สิ่งที่เราต้องทำก็คือส่งค่ากลับตามเงื่อนไขที่กำหนดขึ้น และนี่เป็นเงื่อนไขสำหรับการเรียงจากน้อยไปมาก

  1. เงื่อนไข a < b: เมื่อ a น้อยกว่า b ส่งค่ากลับเป็น -1 เพื่อสลับไปอยู่ทางซ้ายของ b
  2. เงื่อนไข a > b: เมื่อ a มากกว่า b ส่งค่ากลับเป็น 1 เพื่อสลับไปอยู่ทางด้านขวาของ b
  3. ในกรณีที่ค่าเท่ากัน (else): ส่งค่ากลับ 0 ไม่มีการจัดเรียงเกิดขึ้น

ในทางกลับกัน ในกรณีที่เราต้องการเรียงตัวเลขในอาเรย์จากมากไปน้อย เราเพียงแค่สลับเงื่อนไขของการส่งค่ากลับจาก -1 เป็น 1 และจาก 1 เป็น -1 แทน ดังนี้

sort_descending.js
let numbers = [30, 10, 50, 40, 20];
numbers.sort(function (a, b) {
    if (a < b)
        return 1;
    else if (a > b)
        return -1;
    else
        return 0;
});
console.log("Sorted:", numbers);
// Output: Sorted: [ 50, 40, 30, 20, 10 ]

ในตอนนี้ ตัวเลขในอาเรย์จะเรียงจากมากไปน้อยแทน จะเห็นว่าการใช้งานไม่ได้ซับซ้อนเลย การใช้งานเมธอด sort ในรูปแบบ Callback นั้นมักใช้ในกรณีที่เราต้องการเรียงค่าในอาเรย์ของประเภทข้อมูลที่ซับซ้อนหรือเมื่อค่าในอาเรย์ไม่สามารถนำมาเปรียบเทียบกันได้โดยตรง ในตัวอย่างนี้ มาเรียงค่าในอาเรย์โดยใช้คะแนนจากออบเจ็ค

sort_by_property.js
let students = [
    { name: "Chris", score: 68 },
    { name: "Metin", score: 91 },
    { name: "John", score: 30 },
    { name: "Brendan", score: 52 },
    { name: "Mateo", score: 82 },
];

students.sort(function (a, b) {
    if (a.score < b.score) {
        return -1;
    } else if (a.score > b.score) {
        return 1;
    } else {
        return 0;
    }
});

console.log(students);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

[
  { name: 'John', score: 30 },
  { name: 'Brendan', score: 52 },
  { name: 'Chris', score: 68 },
  { name: 'Mateo', score: 82 },
  { name: 'Metin', score: 91 }
]

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

if (a.score < b.score) {
    return -1;
} else if (a.score > b.score) {
    return 1;
} else {
    return 0;
}

เงื่อนไขของการส่งค่ากลับนั้นเหมือนในตัวอย่างก่อนหน้า คือการเรียงจากมากไปน้อยด้วยคะแนน แต่เนื่องจากค่าในอาเรย์นั้นเป็นออบเจ็ค ดังนั้น a และ b ที่ส่งเข้ามาจึงเป็นออบเจ็ค และเราเข้าถึงคะแนนจาก Property score แทน

ก่อนหน้านี้เราได้บอกไปว่าฟังก์ชัน Callback จะต้องส่งค่ากลับเป็น -1, 1 หรือ 0 แต่นั่นเพื่อให้เข้าใจง่าย ในความเป็นจริงแล้ว เราสามารถส่งค่ากลับเป็นตัวเลขลบสำหรับ -1 และส่งค่ากลับเป็นตัวเลขบวกสำหรับ 1 ได้ นั่นทำให้เราสามารถเขียนได้เป็น

// Sort ascending
let numbers = [30, 10, 50, 40, 20];
numbers.sort(function (a, b) {
    return a - b;
});
console.log("Sorted:", numbers);

ผลลัพธ์การทำงานยังคงเป็นเช่นเดิม นั่นเป็นเพราะเมื่อ a น้อยกว่า b ผลลัพธ์จากการลบจะเป็นค่าลบเสมอ และเป็นค่าบวกในกรณีที่ a มากกว่า b และสุดท้ายเมื่อทั้งสองมีค่าเท่ากัน ผลลัพธ์จะเป็น 0

ดังนั้นเมื่อเราต้องการเรียงจากมากไปน้อยแค่กลับค่าโดยการคูณ -1 เข้าในนิพจน์จะได้ดังนี้

// Sort descending
let numbers = [30, 10, 50, 40, 20];
numbers.sort(function (a, b) {
    return (a - b) * -1;
});
console.log("Sorted:", numbers);

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

เราสามารถเขียนมันให้สั้นลงได้อีกโดยการใช้ Arrow function และมันสามารถช่วยลดเวลาในการพิมพ์โค้ดได้

// Using arrow function
let numbers = [30, 10, 50, 40, 20];
numbers.sort((a, b) => a - b);
console.log("Sorted:", numbers);

หมายเหตุ: สำหรับการกำหนดเงื่อนไขแบบสั้น a - b นั้นสามารถทำได้ในกรณีที่ค่าในอาเรย์เป็นตัวเลขเท่านั้น สำหรับค่าในอาเรย์ที่เป็น String หรือออบเจ็คอื่นๆ เราอาจต้องกำหนดเงื่อนการจัดเรียงด้วยตัวเองเช่นเดิม

การใช้งานเมธอด reverse

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

array_reverse.js
let numbers = [1, 2, 3, 4, 5, 6, 7, 8];
let reversed = numbers.reverse();
console.log("Reversed:", reversed);

let names = ["Chris", "Metin", "John", "Brendan", "Mateo"];
console.log("Reversed:", names.reverse());

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Reversed: [
  8, 7, 6, 5,
  4, 3, 2, 1
]
Reversed: [ 'Mateo', 'Brendan', 'John', 'Metin', 'Chris' ]

เมธอด reverse นั้นส่งค่ากลับเป็นอาเรย์ที่ได้รับการกลับลำดับแล้ว คุณได้เห็นตัวอย่างการใช้งานไปแล้วในตอนต้นของบทนี้ เราได้ใช้มันร่วมกับเมธอด sort เพื่อทำให้อาเรย์ที่จัดเรียงจากน้อยไปมาก กลับลำดับเป็นจากมากไปน้อย

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับการจัดเรียงข้อมูลในอาเรย์ด้วยเมธอด sort เราสามารถกำหนดวิธีการจัดเรียงด้วยตัวเองได้โดยการใช้ฟังก์ชัน Callback และเมธอด reverse เพื่อใช้สำหรับกลับลำดับของอาเรย์

บทความนี้เป็นประโยชน์หรือไม่?Yes·No