Tôi đang bị sốc theo nghĩa bóng! Chắc chắn tất cả các câu trả lời là hơi cũ, nhưng thậm chí không ai đề cập đến sự ổn định trong sắp xếp! Vì vậy, hãy kiên nhẫn với tôi, tôi sẽ cố gắng hết sức để trả lời câu hỏi và đi vào chi tiết ở đây. Vì vậy, tôi sẽ xin lỗi bây giờ nó sẽ rất nhiều để đọc.
Vì là năm 2018 nên tôi sẽ chỉ sử dụng ES6, các Polyfills đều có sẵn tại các tài liệu MDN, mà tôi sẽ liên kết ở phần đã cho.
Trả lời câu hỏi:
Nếu các khóa của bạn chỉ là số thì bạn có thể sử dụng an toàn Object.keys()
cùng với Array.prototype.reduce()
để trả về đối tượng đã sắp xếp:
// 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), {}));
Tuy nhiên, nếu bạn đang làm việc với các chuỗi, tôi khuyên bạn nên kết nối Array.prototype.sort()
tất cả những điều này:
// 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), {}));
Nếu ai đó đang tự hỏi những gì giảm làm:
// 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().
}, {});
Nếu cần ở đây là lời giải thích cho một lớp lót:
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.
,{}
);
Tại sao Sắp xếp hơi phức tạp:
Tóm Object.keys()
lại sẽ trả về một mảng có cùng thứ tự như chúng ta nhận được với một vòng lặp bình thường:
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]
Object.keys () trả về một mảng có các phần tử là các chuỗi tương ứng với các thuộc tính có thể đếm được tìm thấy trực tiếp trên đối tượng. Thứ tự của các thuộc tính giống như thứ tự được đưa ra bằng cách lặp qua các thuộc tính của đối tượng theo cách thủ công.
Sidenote - bạn cũng có thể sử dụng Object.keys()
trên các mảng, hãy nhớ rằng chỉ mục sẽ được trả về:
// simple array
const arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
Nhưng nó không dễ dàng như trong các ví dụ đó, các đối tượng trong thế giới thực có thể chứa các số và ký tự chữ cái hoặc thậm chí các ký hiệu (xin đừng làm như vậy).
Dưới đây là một ví dụ với tất cả chúng trong một đối tượng:
// 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' ]
Bây giờ nếu chúng ta sử dụng Array.prototype.sort()
trên mảng phía trên đầu ra thay đổi:
console.log(Object.keys(testObj).sort());
// output: [ '#01010101010', '1000', '1asc', '2', 'b' ]
Đây là một trích dẫn từ các tài liệu:
Phương thức sort () sắp xếp các phần tử của một mảng tại chỗ và trả về mảng. Các loại không nhất thiết phải ổn định. Thứ tự sắp xếp mặc định là theo các điểm mã Unicode chuỗi.
Sự phức tạp về thời gian và không gian của loại không thể được đảm bảo vì nó phụ thuộc vào việc thực hiện.
Bạn phải chắc chắn rằng một trong số chúng trả về đầu ra mong muốn cho bạn. Trong các ví dụ thực tế, mọi người có xu hướng trộn lẫn mọi thứ, đặc biệt nếu bạn sử dụng các thông tin đầu vào khác nhau như API và Cơ sở dữ liệu với nhau.
Vậy thỏa thuận lớn nào?
Vâng, có hai bài viết mà mọi lập trình viên nên hiểu:
Thuật toán tại chỗ :
Trong khoa học máy tính, thuật toán tại chỗ là một thuật toán biến đổi đầu vào không sử dụng cấu trúc dữ liệu phụ trợ. Tuy nhiên, một lượng nhỏ không gian lưu trữ bổ sung được phép cho các biến phụ trợ. Đầu vào thường được ghi đè bởi đầu ra khi thuật toán thực thi. Thuật toán tại chỗ cập nhật trình tự đầu vào chỉ thông qua thay thế hoặc hoán đổi các phần tử. Một thuật toán không tại chỗ đôi khi được gọi là không đúng chỗ hoặc không đúng chỗ.
Vì vậy, về cơ bản mảng cũ của chúng tôi sẽ được ghi đè! Điều này rất quan trọng nếu bạn muốn giữ mảng cũ vì những lý do khác. Vì vậy, hãy ghi nhớ điều này.
Thuật toán sắp xếp
Các thuật toán sắp xếp ổn định sắp xếp các phần tử giống hệt nhau theo cùng thứ tự xuất hiện trong đầu vào. Khi sắp xếp một số loại dữ liệu, chỉ một phần dữ liệu được kiểm tra khi xác định thứ tự sắp xếp. Ví dụ, trong ví dụ sắp xếp thẻ ở bên phải, các thẻ đang được sắp xếp theo thứ hạng của chúng và bộ đồ của chúng bị bỏ qua. Điều này cho phép khả năng nhiều phiên bản được sắp xếp chính xác khác nhau của danh sách gốc. Các thuật toán sắp xếp ổn định chọn một trong số các thuật toán này, theo quy tắc sau: nếu hai mục so sánh bằng nhau, như hai thẻ 5, thì thứ tự tương đối của chúng sẽ được giữ nguyên, do đó, nếu một cái đi trước cái kia trong đầu vào, nó cũng sẽ đến trước cái khác trong đầu ra.
Một ví dụ về loại ổn định trên thẻ chơi. Khi các thẻ được sắp xếp theo thứ hạng với sắp xếp ổn định, hai 5s phải giữ nguyên thứ tự trong đầu ra được sắp xếp mà chúng ban đầu. Khi chúng được sắp xếp với một loại không ổn định, 5s có thể kết thúc ngược lại thứ tự trong đầu ra được sắp xếp.
Điều này cho thấy việc sắp xếp là đúng nhưng nó đã thay đổi. Vì vậy, trong thế giới thực ngay cả khi việc sắp xếp là chính xác, chúng ta phải đảm bảo rằng chúng ta có được những gì chúng ta mong đợi! Đây là siêu quan trọng giữ điều này trong tâm trí là tốt. Để biết thêm các ví dụ JavaScript, hãy xem Array.prototype.sort () - docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort