Sorting in JavaScript
本文介紹了JavaScript中
Array.prototype.sort
方法的一些奇怪的特性。我愛好網站前端設計,以下摘自的我的部落格,原文連結: http://zhangwenli.com/blog/2013/11/02/sorting-in-javascript/。
Method of sorting an array is defined in Array.prototype.sort
. So in most cases, you don't have to think about how to implement a sort algorithm when writing in JavaScript. But you still need to be careful when you use it, since JavaScript is fragile.
What's The Problem?
JavaScript provides sorting method for Array
type, so that you don't have to write it by yourself.
Don't celebrate too early! JavaScript may not behave in the way you think it should.
var colors = ['red', 'green', 'blue', 'yellow', 'white'];
console.log(colors.sort()); // ["blue", "green", "red", "white", "yellow"]
console.log(colors); // ["blue", "green", "red", "white", "yellow"]
Two things we can know from the above example are: Firstly, String
type is sorted in an alphabetic order. Secondly, sort()
method changes the original array rather than generating a new array.
But it's not sorted in an alphabetic order in fact.
var colors = ['red', 'green', 'blue', 'Yellow', 'White'];
console.log(colors.sort()); // ["White", "Yellow", "blue", "green", "red"]
It compares by each character's ASCII code so that uppercase letters are always smaller than lowercase ones.
Another thing you need to be careful with is when you sort an array with numbers.
var money = [12, 3, 7.4, 200];
console.log(money.sort()); // [12, 200, 3, 7.4]
Surprise?
Why
By default, the sort()
method converts everything into String
and then compares letter by letter. You may wonder why JavaScript isn't smart enough to tell this is an array of numbers and then sort it by numbers' value.
But if you think twice, you may find that an array can contain different types in JavaScript, so what do you expect to get from the following sorted array?
var everything = ['Red', '$200', 'white', 7.4, 12, true, 0.3, false];
console.log(everything.sort());
Although I doubt it's a good idea to put all these different types together in an array, this is totally legal in JavaScript. If you think 12
should be thought as larger than 7.4
, then, how to sort the whole array?
OK. Here's how JavaScript deals with it: Convert to String
and compare letter by letter in ASCII code order. So true
is converted to "true"
and false
is converted to "false"
when comparing.
var everything = ['Red', '$200', 'white', 7.4, 12, true, 0.3, false];
console.log(everything.sort());
// ["$200", 0.3, 12, 7.4, "Red", false, true, "white"]
Comparing Function
Sorting arrays with numbers only is still a very common need. So how can I sort them by comparing numbers' value?
Pass a comparing function to it!
Comparing Numbers
var money = [12, 3, 7.4, 200];
var compare = function(a, b) {return a - b;};
console.log(money.sort(compare)); // [3, 7.4, 12, 200]
Now, you get what you wanted.
What happens here is that compare
function takes two element and returns a negative number if a
is smaller than b
, 0
if a
is equal to b
, a positive number if a
is larger than b
.
Comparing Objects
Comparing function is also useful when we compare objects. Let's say that we want to sort people by their id
rather than their name
, we can define a function to compare people by id
.
var people = [{
name: 'Alice',
id: 1234
}, {
name: 'Bob',
id: 567
}];
var compare = function(a, b) {return a.id - b.id;}
console.log(people.sort(compare)); // Bob is before Alice now
Compare Everything
What if we sort everything
with compare
?
var everything = [4, 'Red', '$200', 'white', 7.4, 12, true, 0.3, false];
var compare = function(a, b) {return a - b;};
console.log(everything.sort(compare));
Chrome and Opera: [4, "Red", "$200", "white", false, 0.3, true, 7.4, 12]
;
Firefox: [false, 0.3, true, 4, "Red", "$200", "white", 7.4, 12]
;
IE: ["Red", "$200", false, 0.3, true, 4, "white", 7.4, 12]
.
This is so weird!
When comparing, a - b
is calculated in compare
so that every element in everything
is converted to Number
when comparing and then do the minus operation. As Number('Red')
, Number('$200')
and Number('white')
give NaN
all, comparing function compare
returns NaN
when they compare to any other element. With the existance of this NaN
, the behavior of Array.prototype.sort
is not defined in the ECMA Specification, so it depends on each platform's implementation.
Calling
comparefn(a,b)
always returns the same valuev
when given a specific pair of valuesa
andb
as its two arguments. Furthermore,Type(v)
isNumber
, andv
is notNaN
. Note that this implies that exactly one ofa <CF b
,a =CF b
, anda >CF b
will be true for a given pair of a and b.
The lesson learned here is that the behavior of sorting with a comparing function that will return NaN
is unpredictable and you should be careful when choosing a suitable comparing function. Again, it's not a good idea to put everything with different types all together in the same array.
關於作者
我的部落格主要關注於網站前端設計和程式設計,有興趣的話可以訂閱RSS,謝謝支援!另外,我在圖靈社群出版了電子書《Three.js入門指南》,感興趣的程式猿可以看看~
我的郵箱是OviliaZhang # gmail.com,歡迎交流!
相關文章
- javascript sorting/ v8 sortingJavaScript
- Sorting with Twos
- Homework record-Simple sorting
- LintCode-Topological Sorting
- 347. Top K Frequent Elements - Bucket Sorting
- (DP) CF1861D Sorting By Multiplication
- Sorting 排序演算法: Quick Sort 快速排序排序演算法UI
- PostgreSQL 13支援增量排序(Incremental Sorting)SQL排序REM
- CF1815A Ian and Array Sorting 題解
- (十) 資料庫查詢處理之排序(sorting)資料庫排序
- [PAT]1028. List Sorting (25)@Java實現Java
- CF1982F Sorting Problem Again 題解AI
- Atcoder nomura2020F Sorting GameGAM
- POJ 1094 Sorting It All Out Floyd_Washall+Topological_sort
- 22New Cascalog features: outer joins, combiners, sorting, and more
- POJ 1094-Sorting It All Out(元素大小關係-拓撲排序)排序
- JavaScript高階:JavaScript物件導向,JavaScript內建物件,JavaScript BOM,JavaScript封裝JavaScript物件封裝
- javaScript系列[06]-javaScript和thisJavaScript
- 【JavaScript學習】JavaScript物件建立JavaScript物件
- 【轉】eval()函式(javascript) - [javaScript]函式JavaScript
- [Javascript] How javascript read the property?JavaScript
- JavaScript -"this"JavaScript
- javascript ??JavaScript
- This in JavaScriptJavaScript
- “This” is For JavaScriptJavaScript
- javascript thisJavaScript
- JavaScriptJavaScript
- javaScript系列[05]-javaScript和JSONJavaScriptJSON
- 44 道 JavaScript 難題(JavaScript Puzzlers!)JavaScript
- 【轉向JavaScript系列】AST in Modern JavaScriptJavaScriptAST
- javascript,還是javascript的問題JavaScript
- JavaScript 教程之JavaScript常用框架簡介JavaScript框架
- 《深入理解JavaScript》——2.3 JavaScript有用嗎JavaScript
- 【JavaScript】--JavaScript總結一覽無餘JavaScript
- 【HTML、JAVASCRIPT、CSS】3、Javascript基本概念HTMLJavaScriptCSS
- [Javascript] Understanding JavaScript Proxies with Symbol.toPrimitiveJavaScriptSymbolMIT
- JavaScript EventJavaScript
- JavaScript BackdoorJavaScript