数组排序本来很简单,大多数场景一个sort方法足以搞定,多属性排序在设计参数格式时遇到了点小麻烦,由于对象的属性键值对不支持顺序读取(Map 是支持有序键值对的), 最终将参数设计成 [['a', 'asc'], ['b', 'asc']] 这样的方式了,不过也支持 sortBy([], 'a', 'desc') 。
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
'use strict'
// sortBy([], 'a', 'desc') => sortBy([], [['a', 'desc']])
// sortBy([], ['a', ['b']]) => sortBy([], [['a', 'asc'], ['b', 'asc']])
function sortBy(list, field, order) { // order: 1 asc, -1 desc, 0 ''
if (!list || !list.sort || !list.length) return list
var sort = []
if (typeof field === 'string') {
sort.push([field, order === undefined ? 'asc' : String(order)])
} else if (Object.prototype.toString.call(field) === '[object Array]') {
sort = field
}
for (var i = sort.length - 1; i > -1; i--) {
if (typeof sort[i] === 'string') {
sort[i] = [sort[i], 'asc']
} else if (Object.prototype.toString.call(sort[i]) === '[object Array]') {
if (typeof sort[i][0] !== 'string') sort[i][0] = String(sort[i][0])
if (String(sort[i][1]) === '-1' || String(sort[i][1]).toLowerCase() === 'desc') {
sort[i][1] = 'desc'
} else if (String(sort[i][1]) === '0') {
sort[i][1] = '0'
} else sort[i][1] = 'asc'
}
}
console.log(sort)
list.sort(function(a, b) {
var m, n, result = 0
for (var i = 0, len = sort.length; i < len; i++) {
if (sort[i][1] === '0') continue;
if (Object.prototype.toString.call(a[sort[i][0]]) === '[object Number]'
&& Object.prototype.toString.call(b[sort[i][0]]) === '[object Number]') {
m = a[sort[i][0]]
n = b[sort[i][0]]
} else {
m = String(a[sort[i][0]]).toLowerCase()
n = String(b[sort[i][0]]).toLowerCase()
}
result = (m > n ? 1 : m < n ? -1 : 0) * (sort[i][1] === 'desc' ? -1 : 1)
if (result) break
}
return result
})
return list
}
// sortBy([{a:1,b:2},{a:1,b:3},{a:2,b:2}], [['a',1], ['b', -1]])
// ['a', 'desc', 'b', '', 'c']
// [{key: 'a', order: -1},{key: 'b', order: 1}]
// [['a', -1],['b', 1], 'c', ['d']]
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', -1)) === '[{"a":3,"b":2},{"a":2,"b":2},{"a":1,"b":3}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', '-1')) === '[{"a":3,"b":2},{"a":2,"b":2},{"a":1,"b":3}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', 'desc')) === '[{"a":3,"b":2},{"a":2,"b":2},{"a":1,"b":3}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', 'dEsc')) === '[{"a":3,"b":2},{"a":2,"b":2},{"a":1,"b":3}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', 0)) === '[{"a":3,"b":2},{"a":1,"b":3},{"a":2,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', '0')) === '[{"a":3,"b":2},{"a":1,"b":3},{"a":2,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', 1)) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', '1')) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', 'asc')) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a', 'aSc')) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], 'a')) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], ['a'])) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', -1]])) === '[{"a":3,"b":2},{"a":2,"b":2},{"a":1,"b":3}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', '-1']])) === '[{"a":3,"b":2},{"a":2,"b":2},{"a":1,"b":3}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', 'desc']])) === '[{"a":3,"b":2},{"a":2,"b":2},{"a":1,"b":3}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', 'dEsc']])) === '[{"a":3,"b":2},{"a":2,"b":2},{"a":1,"b":3}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', 1]])) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', '1']])) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', 'asc']])) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', 'aSc']])) === '[{"a":1,"b":3},{"a":2,"b":2},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', 0]])) === '[{"a":3,"b":2},{"a":1,"b":3},{"a":2,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:1,b:3},{a:2,b:2}], [['a', '0']])) === '[{"a":3,"b":2},{"a":1,"b":3},{"a":2,"b":2}]')
console.log(JSON.stringify(sortBy([{a:3,b:2},{a:3,b:3},{a:2,b:2}], ['a', ['b', -1]])) === '[{"a":2,"b":2},{"a":3,"b":3},{"a":3,"b":2}]')
console.log(JSON.stringify(sortBy([{a:1,b:2},{a:1,b:3},{a:2,b:2}], [['a', -1], ['b', -1]])) === '[{"a":2,"b":2},{"a":1,"b":3},{"a":1,"b":2}]')
</script>
</body>
</html>