พวกฉันตกใจเป็นรูปเป็นร่าง! แน่นอนว่าคำตอบทั้งหมดค่อนข้างเก่า แต่ก็ไม่มีใครพูดถึงเสถียรภาพในการเรียงลำดับ! ดังนั้นทนกับฉันฉันจะพยายามอย่างดีที่สุดเพื่อตอบคำถามตัวเองและไปที่รายละเอียดที่นี่ ดังนั้นฉันจะขอโทษตอนนี้มันจะเป็นจำนวนมากที่จะอ่าน
เนื่องจากเป็นปี 2018 ฉันจะใช้ ES6 เท่านั้น Polyfills จึงมีอยู่ใน MDN docs ซึ่งฉันจะเชื่อมโยงในส่วนที่กำหนด
ตอบคำถาม:
หากคีย์ของคุณเป็นตัวเลขเท่านั้นคุณสามารถใช้Object.keys()
ร่วมกับArray.prototype.reduce()
เพื่อส่งคืนวัตถุที่เรียงลำดับได้อย่างปลอดภัย:
// Only numbers to show it will be sorted.
const testObj = {
'2000': 'Articel1',
'4000': 'Articel2',
'1000': 'Articel3',
'3000': 'Articel4',
};
// I'll explain what reduces does after the answer.
console.log(Object.keys(testObj).reduce((accumulator, currentValue) => {
accumulator[currentValue] = testObj[currentValue];
return accumulator;
}, {}));
/**
* expected output:
* {
* '1000': 'Articel3',
* '2000': 'Articel1',
* '3000': 'Articel4',
* '4000': 'Articel2'
* }
*/
// if needed here is the one liner:
console.log(Object.keys(testObj).reduce((a, c) => (a[c] = testObj[c], a), {}));
อย่างไรก็ตามหากคุณกำลังทำงานกับสตริงฉันขอแนะนำให้ผูกมัดArray.prototype.sort()
กับสิ่งนี้ทั้งหมด:
// String example
const testObj = {
'a1d78eg8fdg387fg38': 'Articel1',
'z12989dh89h31d9h39': 'Articel2',
'f1203391dhj32189h2': 'Articel3',
'b10939hd83f9032003': 'Articel4',
};
// Chained sort into all of this.
console.log(Object.keys(testObj).sort().reduce((accumulator, currentValue) => {
accumulator[currentValue] = testObj[currentValue];
return accumulator;
}, {}));
/**
* expected output:
* {
* a1d78eg8fdg387fg38: 'Articel1',
* b10939hd83f9032003: 'Articel4',
* f1203391dhj32189h2: 'Articel3',
* z12989dh89h31d9h39: 'Articel2'
* }
*/
// again the one liner:
console.log(Object.keys(testObj).sort().reduce((a, c) => (a[c] = testObj[c], a), {}));
หากมีคนสงสัยว่าการลดราคาทำอย่างไร:
// Will return Keys of object as an array (sorted if only numbers or single strings like a,b,c).
Object.keys(testObj)
// Chaining reduce to the returned array from Object.keys().
// Array.prototype.reduce() takes one callback
// (and another param look at the last line) and passes 4 arguments to it:
// accumulator, currentValue, currentIndex and array
.reduce((accumulator, currentValue) => {
// setting the accumulator (sorted new object) with the actual property from old (unsorted) object.
accumulator[currentValue] = testObj[currentValue];
// returning the newly sorted object for the next element in array.
return accumulator;
// the empty object {} ist the initial value for Array.prototype.reduce().
}, {});
หากจำเป็นนี่คือคำอธิบายสำหรับสายการบินเดียว:
Object.keys(testObj).reduce(
// Arrow function as callback parameter.
(a, c) =>
// parenthesis return! so we can safe the return and write only (..., a);
(a[c] = testObj[c], a)
// initial value for reduce.
,{}
);
ทำไมการเรียงลำดับค่อนข้างซับซ้อน:
ในระยะสั้นObject.keys()
จะส่งกลับอาร์เรย์ที่มีคำสั่งเดียวกับที่เราได้รับกับวงปกติ:
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]
Object.keys () ส่งคืนอาร์เรย์ที่มีองค์ประกอบเป็นสตริงที่สอดคล้องกับคุณสมบัติที่นับได้ที่พบโดยตรงกับวัตถุ การเรียงลำดับของคุณสมบัติเหมือนกับที่กำหนดโดยการวนลูปมากกว่าคุณสมบัติของวัตถุด้วยตนเอง
Sidenote - คุณสามารถใช้Object.keys()
กับอาร์เรย์ได้เช่นกันโปรดจำไว้ว่าดัชนีจะถูกส่งคืน:
// simple array
const arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
แต่มันไม่ง่ายอย่างที่แสดงในตัวอย่างวัตถุในโลกแห่งความจริงอาจมีตัวเลขและตัวอักษรหรือแม้แต่สัญลักษณ์ (โปรดอย่าทำ)
นี่คือตัวอย่างที่มีทั้งหมดในวัตถุเดียว:
// This is just to show what happens, please don't use symbols in keys.
const testObj = {
'1asc': '4444',
1000: 'a',
b: '1231',
'#01010101010': 'asd',
2: 'c'
};
console.log(Object.keys(testObj));
// output: [ '2', '1000', '1asc', 'b', '#01010101010' ]
ทีนี้ถ้าเราใช้Array.prototype.sort()
กับอาเรย์ข้างบนการเปลี่ยนแปลงเอาท์พุต:
console.log(Object.keys(testObj).sort());
// output: [ '#01010101010', '1000', '1asc', '2', 'b' ]
นี่คือคำพูดจากเอกสาร:
sort () วิธีการเรียงลำดับองค์ประกอบของอาร์เรย์ในสถานที่และส่งกลับอาร์เรย์ การเรียงลำดับไม่จำเป็นต้องมีเสถียรภาพ ลำดับการเรียงเริ่มต้นเป็นไปตามจุดรหัส Unicode ของสตริง
ไม่สามารถรับประกันความซับซ้อนของเวลาและพื้นที่ของการจัดเรียงได้เนื่องจากขึ้นอยู่กับการใช้งาน
คุณต้องตรวจสอบให้แน่ใจว่าหนึ่งในนั้นส่งคืนผลลัพธ์ที่ต้องการสำหรับคุณ ในตัวอย่าง reallife คนมักจะรวมสิ่งต่าง ๆ โดยเฉพาะอย่างยิ่งถ้าคุณใช้ข้อมูลที่แตกต่างกันเช่น API และฐานข้อมูลเข้าด้วยกัน
ดังนั้นเรื่องใหญ่คืออะไร
มีสองบทความที่โปรแกรมเมอร์ทุกคนควรเข้าใจคือ
อัลกอริธึมแบบแทนที่ :
ในวิทยาการคอมพิวเตอร์อัลกอริทึมแบบแทนที่คืออัลกอริธึมที่แปลงอินพุตโดยไม่มีโครงสร้างข้อมูลเสริม อย่างไรก็ตามอนุญาตให้มีพื้นที่เก็บข้อมูลจำนวนเล็กน้อยสำหรับตัวแปรเสริม โดยทั่วไปอินพุตจะถูกเขียนทับโดยเอาต์พุตเมื่ออัลกอริทึมทำงาน อัลกอริธึมแบบเข้าแทนที่จะอัปเดตลำดับอินพุตผ่านการแทนที่หรือการเปลี่ยนองค์ประกอบเท่านั้น อัลกอริทึมที่ไม่ได้อยู่ในสถานที่บางครั้งเรียกว่าไม่ได้อยู่ในสถานที่หรือนอกสถานที่
ดังนั้นโดยทั่วไปอาร์เรย์เก่าของเราจะถูกเขียนทับ! สิ่งนี้สำคัญถ้าคุณต้องการเก็บอาเรย์เก่าด้วยเหตุผลอื่น ดังนั้นจงเก็บเรื่องนี้ไว้ในใจ
ขั้นตอนวิธีการเรียงลำดับ
อัลกอริทึมการเรียงลำดับที่เสถียรจัดเรียงองค์ประกอบที่เหมือนกันในลำดับเดียวกันกับที่ปรากฏในอินพุต เมื่อเรียงลำดับข้อมูลบางประเภทจะมีการตรวจสอบข้อมูลบางส่วนเท่านั้นเมื่อพิจารณาลำดับการจัดเรียง ตัวอย่างเช่นในตัวอย่างการเรียงลำดับบัตรทางด้านขวาการ์ดจะถูกเรียงลำดับตามระดับของบัตรและชุดไพ่จะถูกละเว้น สิ่งนี้ทำให้เกิดความเป็นไปได้ของรายการดั้งเดิมที่เรียงลำดับอย่างถูกต้องหลายรายการ อัลกอริธึมการเรียงลำดับที่เสถียรเลือกหนึ่งในสิ่งเหล่านี้ตามกฎต่อไปนี้: หากรายการสองรายการเปรียบเทียบเท่ากันเช่นสองไพ่ 5 ใบลำดับที่สัมพันธ์กันของพวกเขาจะถูกเก็บรักษาไว้เพื่อที่ว่าหากมีใครมาก่อน มาก่อนอื่น ๆ ในการส่งออก
ตัวอย่างของการเรียงไพ่ที่มีเสถียรภาพ เมื่อการ์ดถูกจัดเรียงตามลำดับที่มีการจัดเรียงที่เสถียรทั้งสอง 5s จะต้องอยู่ในลำดับเดียวกันในเอาต์พุตที่เรียงลำดับซึ่งพวกเขาอยู่ในขั้นต้นเมื่อพวกเขาเรียงลำดับด้วยการเรียงที่ไม่เสถียรที่ 5s อาจจบลงในทางตรงกันข้าม เรียงลำดับผลลัพธ์
นี่แสดงให้เห็นว่าการเรียงลำดับนั้นถูกต้อง แต่เปลี่ยนไป ดังนั้นในโลกแห่งความจริงแม้ว่าการเรียงลำดับจะถูกต้องเราต้องแน่ใจว่าเราได้รับสิ่งที่เราคาดหวัง! นี่เป็นสิ่งที่สำคัญอย่างยิ่ง สำหรับตัวอย่าง JavaScript เพิ่มเติมให้ดูที่ Array.prototype.sort () - docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort