js中用 sort()
方法为数组排序。sort()
方法有一个可选参数,是用来肯定元素顺序的函数。若是这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序。如:javascript
var arr = ["a", "A", "c", "B"]; arr.sort(); console.log(arr); // ["A", "B", "a", "c"]
注意:
sort()
方法在在原数组上进行排序,不生成副本。
由于字母A、B的ASCII值分别为6五、66,而a、b的值分别为9七、99,因此上面输出的结果是 ["A", "B", "a", "c"]
。html
若是数组元素是数字呢,结果会是怎样?java
var arr = [15, 8, 25, 3]; arr.sort(); console.log(arr); // [15, 25, 3, 8]
结果是 [15, 25, 3, 8]
。其实,sort方法会调用每一个元素的 toString()
方法,获得字符串,而后再对获得的字符串进行排序。虽然数值15比3大,但在进行字符串比较时"15"则排在"3"前面。显然,这种结果不是咱们想要的,这时,sort()
方法的参数就起到了做用,咱们把这个参数叫作比较函数。windows
比较函数接收两个参数,若是第一个参数应该位于第二个以前则返回一个负数,若是第一个参数应该位于第二个以后则返回一个正数,若是两个参数相等则返回0。例子:数组
var arr = [23, 9, 4, 78, 3]; // 比较函数 var compare = function (x, y) { if (x < y) { return -1; } else if (x > y) { return 1; } else { return 0; } } console.log(arr.sort(compare));
结果为 [3, 4, 9, 23, 78]
,返回了咱们想要的结果。若是要按降序排序,比较函数写成这样便可:服务器
var compare = function (x, y) { if (x < y) { return 1; } else if (x > y) { return -1; } else { return 0; } }
咱们并不能用比较函数比较一个不能转化为数字的字符串与数字的顺序:函数
var arr = ["b", 5]; console.log(arr.sort(compare))
结果是 ["b", 5]
。由于比较函数在比较时,会把先把字符串转化为数字,而后再比较,字符串b不能转化为数字,因此就不能比较大小。然而,当不用比较函数时,会比较ASCII值,因此结果是 [5, "b"]
。code
若是数组项是对象,咱们须要根据数组项的某个属性对数组进行排序,要怎么办呢?其实和前面的比较函数也差很少:htm
var arr = [{name: "zlw", age: 24}, {name: "wlz", age: 25}]; var compare = function (obj1, obj2) { var val1 = obj1.name; var val2 = obj2.name; if (val1 < val2) { return -1; } else if (val1 > val2) { return 1; } else { return 0; } } console.log(arr.sort(compare));
输出结果为 [{ name="wlz", age=25}, { name="zlw", age=24}]
,能够看到数组已经按照 name
属性进行了排序。咱们能够对上面的比较函数再改造一下:对象
var compare = function (prop) { return function (obj1, obj2) { var val1 = obj1[prop]; var val2 = obj2[prop]; if (val1 < val2) { return -1; } else if (val1 > val2) { return 1; } else { return 0; } } }
若是想按照 age
进行排序,arr.sort(compare("age"))
便可。
可是对age属性进行排序时须要注意了,若是age属性的值是数字,那么排序结果会是咱们想要的。但不少时候咱们从服务器传回来的数据中,属性值一般是字符串。如今我把上面的数组改成:
var arr = [{name: "zlw", age: "24"}, {name: "wlz", age: "5"}];
能够看到,我把 age
属性由数字改成了字符串,第二个数组项的 age
值改成了 "5"
。再次调用 arr.sort(compare("age"))
后,结果为:
[Object { name="zlw", age="24"}, Object { name="wlz", age="5"}]
咱们的指望是5排在24前面,可是结果不是。这是由于当两个数字字符串比较大小时,会比较它们的ASCII值大小,比较规则是:从第一个字符开始,顺次向后直到出现不一样的字符为止,而后以第一个不一样的字符的ASCII值肯定大小。因此"24"与"5"比较大小时,先比较”2“与"5"的ASCII值,显然”2“的ASCII值比"5"小,即肯定排序顺序。
如今,咱们须要对比较函数再作一些修改:
var compare = function (prop) { return function (obj1, obj2) { var val1 = obj1[prop]; var val2 = obj2[prop]; if (!isNaN(Number(val1)) && !isNaN(Number(val2))) { val1 = Number(val1); val2 = Number(val2); } if (val1 < val2) { return -1; } else if (val1 > val2) { return 1; } else { return 0; } } }
在比较函数中,先把比较属性值转化为数字 Number(val1)
再经过 !isNaN(Number(val1))
判断转化后的值是否是数字(有多是NaN),转化后的值若是是数字,则比较转换后的值,这样就能够获得咱们想要的结果了, 调用 arr.sort(compare("age"))
获得:
[Object { name="wlz", age="5"}, Object { name="zlw", age="24"}]
能够看到,确实是按正确的方式排序了。
以上内容参考: https://www.cnblogs.com/xljzl...
前面咱们都已了解数组中的元素将按照ASCII字符顺序进行排序,数组中元素为字母与数字混合时,正常排序是这样的:
var arr = ["a11", "C", "a2", "C4", "C33"]; arr.sort(); console.log(arr); // ["C", "C33", "C4", "a11", "a2"]
咱们发现 C33
在 C4 的前面,a11 在a2的前面,可能这种排序方式不能知足一些需求,若是咱们的需求是这样:前面字母相同的状况下,后面根据数字的大小来排序。如上面的例子要排成 ["C", "C4", "C33", "a2", "a11"]
这样的结果,咱们就须要用到正则了,能够这样来实现:
var reA = /[^a-zA-Z]/g; var reN = /[^0-9]/g; function sortAlphaNum(a, b) { var aA = a.replace(reA, ""); var bA = b.replace(reA, ""); if (aA === bA) { var aN = parseInt(a.replace(reN, ""), 10); var bN = parseInt(b.replace(reN, ""), 10); return aN === bN ? 0 : aN > bN ? 1 : -1; } else { return aA > bA ? 1 : -1; } } var arr = ["A1", "A10", "A11", "A12", "A2", "A3", "A4", "B10", "B2", "F1", "F12", "F3"]; arr.sort(sortAlphaNum); // ["A1", "A2", "A3", "A4", "A10", "A11", "A12", "B2", "B10", "F1", "F3", "F12"]
对象数组的实现方案也是相似,只是须要添加须要排序的key名:
var reA = /[^a-zA-Z]/g; var reN = /[^0-9]/g; function sortAlphaNum(a, b) { var aA = a.name.replace(reA, ""); var bA = b.name.replace(reA, ""); if (aA === bA) { var aN = parseInt(a.name.replace(reN, ""), 10); var bN = parseInt(b.name.replace(reN, ""), 10); return aN === bN ? 0 : aN > bN ? 1 : -1; } else { return aA > bA ? 1 : -1; } } var singers = [ { name: 'Ttevie Nicks', band: 'Fleetwood Mac', born: 1948 }, { name: 'Steven Tyler101', band: 'Aerosmith', born: 1948 }, { name: 'Steven Tyler11', band: 'The Carpenters', born: 1950 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Stevie Nick', band: 'Fleetwood Mac', born: 1948 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, { name: 'Kurt Coba35in', band: 'Nirvana', born: 1967 }, { name: 'Kurt Cobai35n', band: 'Nirvana', born: 1967 }, ]; console.log(singers.sort(sortAlphaNum)); // 输出结果 // [ // {name: "Kurt Coba35in", band: "Nirvana", born: 1967} // 1: {name: "Kurt Cobai35n", band: "Nirvana", born: 1967} // 2: {name: "Kurt Cobain", band: "Nirvana", born: 1967} // 3: {name: "Steven Tyler11", band: "The Carpenters", born: 1950} // 4: {name: "Steven Tyler101", band: "Aerosmith", born: 1948} // 5: {name: "Stevie Nick", band: "Fleetwood Mac", born: 1948} // 6: {name: "Stevie Nicks", band: "Fleetwood Mac", born: 1948} // 7: {name: "Ttevie Nicks", band: "Fleetwood Mac", born: 1948} // ]
对上面的对比函数进行改造:
var sortAlphaNum = function (key) { return function (a, b) { var aA = a[key].replace(reA, ""); var bA = b[key].replace(reA, ""); if (aA === bA) { var aN = parseInt(a[key].replace(reN, ""), 10); var bN = parseInt(b[key].replace(reN, ""), 10); return aN === bN ? 0 : aN > bN ? 1 : -1; } else { return aA > bA ? 1 : -1; } } }
能够直接指定key进行排序:
singers.sort(sortAlphaNum('name'));
这种排序方式和windows文件名/文件夹排序方式基本相同