Sử dụng phương pháp sắp xếp của JavaScript để sắp xếp các mảng chuỗi
Phương thức sort
có sẵn trên nguyên mẫu Mảng cho phép bạn sắp xếp các phần tử của một mảng. Nó chấp nhận một chức năng gọi lại tùy chọn mà bạn có thể sử dụng để điều chỉnh cơ chế sắp xếp theo nhu cầu cụ thể của bạn .
Đối với mảng số, hãy tham khảo bài đăng trước của ta về cách sắp xếp mảng số .
Việc sắp xếp các chuỗi có thể khá khó hiểu vì cách thức hoạt động của phương pháp sort
.
Đầu tiên, tiêu chuẩn ECMAScript không chỉ định một thuật toán sắp xếp cụ thể, tất cả phụ thuộc vào từng nhà cung cấp trình duyệt.
Thứ hai, vỏ đóng một role quan trọng khi phân loại. Để việc sắp xếp hoạt động, cần phải có sự sắp xếp theo thứ tự của các thứ và điều này có thể đạt được với các con số - các con số liên tục tự nhiên (1, 2, 3, 4…). Khi các chuỗi đang được so sánh, chúng được chuyển đổi thành giá trị Unicode tương đương - không có gì đáng ngạc nhiên là các số, sau đó được sắp xếp tuần tự, theo thứ tự tăng dần theo mặc định.
Giá trị Unicode cho các ký tự
Để lấy giá trị Unicode của mỗi ký tự - viết thường hoặc viết hoa, ta sử dụng phương thức chuỗi charCodeAt
để truy cập mã ký tự của một index ký tự được chỉ định.
Ở lại với tôi.
Ta sẽ bắt đầu bằng cách tạo các hàm tiện ích giúp lấy các giá trị unicode của các ký tự cũng như các ký tự. Ta sẽ đề cập đến chúng khi ta đi.
// get Unicode values of character items in an array
function getCharactersUnicodeValue(characters) {
const unicodeChart = new Map();
characters.forEach(character => {
unicodeChart.set(
character,
character.charCodeAt(character.indexOf(character))
);
});
console.table(unicodeChart);
}
// get unicode values of a single character
function getCharacterUnicodeValue(character) {
const value = character.charCodeAt(character.indexOf(character));
console.log(value);
}
Lưu ý việc sử dụng Bản đồ tại đây.
Ta sẽ gọi các chức năng tiện ích như:
getCharactersUnicodeValue("ABCDEFabcdef".split("")); // array of characters: [ 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f' ]
// Result: {character → Unicode Value}
// { A → 65, B → 66, C → 67, D → 68, E → 69, F → 70, a → 97, b → 98, c → 99, d → 100, e → 101, f → 102 }
getCharacterUnicodeValue("A");
// Result: {character → Unicode Value}
// { A → 65 }
Và đây là một ví dụ khác:
const crocodilian = "crOCoDiliaN".split(""); // array of characters i.e [ 'c', 'r', 'O', 'C', 'o', 'D', 'i', 'l', 'i', 'a', 'N' ]
getCharactersUnicodeValue(crocodilian);
// Result: {character → Unicode Value}
// { c → 99, r → 114, O → 79, C → 67, o → 111, D → 68, i → 105, l → 108, a → 97, N → 78 }
Lưu ý các ký tự UPPERCASE xuất hiện trước các ký tự viết thường . Và họ sẽ đến tuần tự. Nó được sắp xếp như sau: ['Eggs', 'Tail', 'eggs']
. Để ý xem Tail
đến trước eggs
như thế nào? Điều đó được mong đợi bởi vì:
getCharactersUnicodeValue(["Eggs", "Tail", "eggs"]);
// Result: {character → Unicode Value}
// { Eggs → 69, Tail → 84, eggs → 101 }
// 84 (T) of Tail comes numerically before 101 (e) of eggs
TL; DR : Việc sắp xếp khi một chuỗi chỉ được tạo thành với cùng một trường hợp (viết hoa hoặc viết thường) thật dễ dàng. Thử thách chỉ đến với các trường hợp hỗn hợp.
Sắp xếp các chuỗi trường hợp hỗn hợp
Hầu hết thời gian ta sẽ muốn mảng của ta về trường hợp chuỗi hỗn hợp để được sắp xếp không phụ thuộc vào vỏ.
const things = [ 'nest', 'Eggs', 'bite', 'gator', 'caYman', 'Grip', 'grips', 'Jaw', 'crocodilian', 'Bayou' ];
Cuối cùng sẽ được sắp xếp như sau:
[ 'Bayou', 'bite', 'caYman', 'crocodilian', 'Eggs', 'gator', 'Grip', 'grips', 'Jaw', 'nest' ]
Và không:
[ 'Bayou', 'Eggs', 'Grip', 'Jaw', 'bite', 'caYman', 'crocodilian', 'gator', 'grips', 'nest' ]
Nỗ lực một: Không có chức năng so sánh
Gọi phương thức sắp xếp mà không có hàm so sánh sẽ không hoạt động:
things.sort();
// ['Bayou', 'Eggs', 'Grip', 'Jaw', 'bite', 'caYman', 'crocodilian', 'gator', 'grips', 'nest']
Nỗ lực thứ hai: Với chức năng so sánh
function sortThings(a, b) {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else if (a === b) {
return 0;
}
}
Sau đó sắp xếp bằng comparison function
:
things.sort(sortThings);
// [ 'Bayou', 'Eggs', 'Grip', 'Jaw', 'bite', 'caYman', 'crocodilian', 'gator', 'grips', 'nest' ]
Tuy nhiên, nó không hoạt động. Trên thực tế, ta cũng có thể đã không viết một hàm so sánh .
Nỗ lực ba: Với chức năng so sánh và trường hợp chung
Vấn đề là việc sắp xếp vẫn sử dụng các trường hợp hỗn hợp mặc định của các phần tử mảng thứ mà ta cần làm là chuyển đổi các trường hợp thành một trường hợp chung - chữ thường hoặc chữ UPPERCASE sẽ làm.
function sortThings(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else if (a === b) {
return 0;
}
}
Hoặc, sử dụng toán tử bậc ba:
function sortThings(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
return a > b ? -1 : b > a ? 1 : 0;
}
Sau đó sắp xếp lại bằng comparison function
:
things.sort(sortThings);
// ['Bayou', 'bite', 'caYman', 'crocodilian', 'Eggs', 'gator', 'Grip', 'grips', 'Jaw', 'nest' 'eggz']
Và bạn thấy nó hoạt động ngay bây giờ!
Nhưng xin chờ chút nữa
Mặc dù các nhà cung cấp trình duyệt có thuật toán sắp xếp cụ thể của họ, nhưng có một số kỹ thuật mà ta nên làm quen. Việc sắp xếp được thực hiện trên cơ sở charCodeAt(index)
. Trong trường hợp hai mục so sánh gần như tương tự nhau, charCodeAt(index)
được so sánh liên tục. Nơi index bắt đầu từ 0 cho đến khi có sự khác biệt.
Lấy eggs
và Eggz
làm ví dụ:
Nếu không chuyển đổi thành chữ thường,
Eggz
sẽ đứng trướceggs
vì giá trị Unicode củaE → 69
đứng trước giá trị củae → 101
.Khi có một chuyển đổi sang một trường hợp tương tự - chữ thường ví dụ - ta đang chủ yếu so sánh
eggs
vàeggz
.e → 101
vàe → 101
bằng nhau.
Đang chạy:
['Eggz', 'eggs'].sort(sortThings);
// ['eggs', 'Eggz']
Sắp xếp chính xác với các ký tự cuối cùng s → 115 and z → 122
là các ký tự xác định.
Việc kiểm tra diễn ra như sau:
- [e → 101] ggs và [e → 101] ggz / 101 === 101, ta chuyển sang các ký tự tiếp theo
- e [g → 103] gs và e [g → 103] gz / 103 === 103, ta chuyển sang các ký tự tiếp theo
- ví dụ [g → 103] s và ví dụ [g → 103] z / 103 === 103, ta chuyển sang các ký tự tiếp theo
- egg [s → 115] và egg [z → 122] / hiển nhiên, 115 đến trước 122.
Et voilà, điều đó quyết định cuộc đấu tay đôi!
Thứ tự giảm dần
Nếu bạn cần sắp xếp theo thứ tự giảm dần, chỉ cần swap trả về 1 trong hàm so sánh với trả về -1 như sau:
function sortThings(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a > b) {
return -1;
} else if (b > a) {
return 1;
} else {
return 0;
}
}
Hoặc là:
function sortThings(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
return a > b ? -1 : b > a ? 1 : 0;
}
Hoặc chỉ cần reverse
mảng đã sắp xếp bằng phương thức reverse
mảng, rõ ràng là đảo ngược mảng thành chuỗi ngược lại:
things.sort(sortThings).reverse();
Thay thế: Sử dụng localeCompare
Mặc dù phương thức chuỗi localeCompare có thể so sánh các ký tự mà không liên quan đến trường hợp được sử dụng, đó là một phương thức chuỗi nên không thể sử dụng trực tiếp trên một mảng. Để sắp xếp mảng things
của ta bằng phương thức chuỗi localeCompare
, ta chuyển localeCompare
làm hàm so sánh như sau:
things.sort((a, b) => a.localeCompare(b));
// [ 'Bayou', 'bite', 'caYman', 'crocodilian', 'Eggs', 'gator', 'Grip', 'grips', 'Jaw', 'nest' ]
Trong nháy mắt mã
const things = [
"nest",
"Eggs",
"bite",
"gator",
"caYman",
"Grip",
"grips",
"Jaw",
"crocodilian",
"Bayou"
];
console.log(`unsorted: ${things.join(", ")}`);
function sortThings(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
return a > b ? 1 : b > a ? -1 : 0;
}
console.log(`sorted: ${things.sort(sortThings).join(", ")}`);
Lưu ý , hãy tiếp tục phân loại, thế giới cần nó.
Các tin liên quan