Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

แก้ปัญหาเมธอด .sort() ใน JavaScript: สองอาร์เรย์ถูกเรียงแทนที่จะเป็นอันเดียว

คุณสมบัติหนึ่งของฟังก์ชัน Array.prototype.sort() คือเป็นอัลกอริทึมการเรียงลำดับแบบ in-place (ในที่เดิม) หมายความว่ามันไม่สร้างสำเนาใหม่ของอาร์เรย์ที่จะถูกเรียง มันเรียงอาร์เรย์โดยไม่ใช้พื้นที่เพิ่มเติม ทำให้มีประสิทธิภาพและประสิทธิภาพการทำงานที่ดีกว่า แต่คุณสมบัตินี้บางครั้งนำไปสู่สถานการณ์ที่ผิดปกติ

มาทำความเข้าใจด้วยตัวอย่าง สมมติว่าเรามีอาร์เรย์ names ที่มีสตริงลิเทอรัล เราต้องการรักษาลำดับของอาร์เรย์นี้ไว้ และต้องการอีกอาร์เรย์หนึ่งที่มีสมาชิกเหมือนกันแต่เรียงตามลำดับอักษร

เราอาจทำแบบนี้

const names = ['Rakesh', 'Mukesh', 'Ram', 'Anshul', 'Dheeraj'];
let sortedNames = names;
sortedNames = sortedNames.sort();
console.log(names);
console.log(sortedNames);

แต่ใน JavaScript อาร์เรย์ก็เป็นอ็อบเจกต์ และอ็อบเจกต์ถูกคัดลอกโดยอ้างอิง (reference) ไม่ใช่โดยค่า (value) ดังนั้นการเรียงอาร์เรย์หนึ่งจึงทำให้อาร์เรย์ทั้งสองถูกเรียง ซึ่งเราไม่ต้องการ

วิธีแก้ไข

1. ใช้ slice() ขณะสร้างอาร์เรย์ใหม่

ตัวอย่าง

const names = ['Rakesh', 'Mukesh', 'Ram', 'Anshul', 'Dheeraj'];
let sortedNames = names.slice();
sortedNames = sortedNames.sort();
console.log(names);
console.log(sortedNames);

เมธอด slice() จริงๆ แล้วคืนค่าสำเนาลึกปาน (shallow copy) ที่คัดลอกเข้าไปในอาร์เรย์ใหม่ หากไม่ระบุอาร์กิวเมนต์ จะคัดลอกตั้งแต่ต้นจนจบ

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

2. ใช้ JSON.stringify() / JSON.parse()

ตัวอย่าง

const names = ['Rakesh', 'Mukesh', 'Ram', 'Anshul', 'Dheeraj'];
let sortedNames = JSON.parse(JSON.stringify(names));
sortedNames = sortedNames.sort();
console.log(names);
console.log(sortedNames);

การแปลงอาร์เรย์เป็นสตริง JSON และกลับมาอีกครั้ง บังคับให้คอมไพเลอร์ไม่คัดลอกโดยอ้างอิง

ผลลัพธ์ของทั้งสองวิธีจะเหมือนกันในคอนโซล

ผลลัพธ์

[ 'Rakesh', 'Mukesh', 'Ram', 'Anshul', 'Dheeraj' ]
[ 'Anshul', 'Dheeraj', 'Mukesh', 'Rakesh', 'Ram' ]