orderBy.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. var arrayEach = require('./arrayEach')
  2. var toArray = require('./toArray')
  3. var map = require('./map')
  4. var isArray = require('./isArray')
  5. var isFunction = require('./isFunction')
  6. var isPlainObject = require('./isPlainObject')
  7. var isUndefined = require('./isUndefined')
  8. var isNull = require('./isNull')
  9. var eqNull = require('./eqNull')
  10. var get = require('./get')
  11. var property = require('./property')
  12. var ORDER_PROP_ASC = 'asc'
  13. var ORDER_PROP_DESC = 'desc'
  14. // function handleSort (v1, v2) {
  15. // return v1 > v2 ? 1 : -1
  16. // }
  17. // '' < 数字 < 字符 < null < undefined
  18. function handleSort (v1, v2) {
  19. if (isUndefined(v1)) {
  20. return 1
  21. }
  22. if (isNull(v1)) {
  23. return isUndefined(v2) ? -1 : 1
  24. }
  25. return v1 && v1.localeCompare ? v1.localeCompare(v2) : (v1 > v2 ? 1 : -1)
  26. }
  27. function buildMultiOrders (name, confs, compares) {
  28. return function (item1, item2) {
  29. var v1 = item1[name]
  30. var v2 = item2[name]
  31. if (v1 === v2) {
  32. return compares ? compares(item1, item2) : 0
  33. }
  34. return confs.order === ORDER_PROP_DESC ? handleSort(v2, v1) : handleSort(v1, v2)
  35. }
  36. }
  37. function getSortConfs (arr, list, fieldConfs, context) {
  38. var sortConfs = []
  39. fieldConfs = isArray(fieldConfs) ? fieldConfs : [fieldConfs]
  40. arrayEach(fieldConfs, function (handle, index) {
  41. if (handle) {
  42. var field = handle
  43. var order
  44. if (isArray(handle)) {
  45. field = handle[0]
  46. order = handle[1]
  47. } else if (isPlainObject(handle)) {
  48. field = handle.field
  49. order = handle.order
  50. }
  51. sortConfs.push({
  52. field: field,
  53. order: order || ORDER_PROP_ASC
  54. })
  55. arrayEach(list, isFunction(field) ? function (item, key) {
  56. item[index] = field.call(context, item.data, key, arr)
  57. } : function (item) {
  58. item[index] = field ? get(item.data, field) : item.data
  59. })
  60. }
  61. })
  62. return sortConfs
  63. }
  64. /**
  65. * 将数组进行排序
  66. *
  67. * @param {Array} arr 数组
  68. * @param {Function/String/Array} fieldConfs 方法或属性
  69. * @param {Object} context 上下文
  70. * @return {Array}
  71. */
  72. function orderBy (arr, fieldConfs, context) {
  73. if (arr) {
  74. if (eqNull(fieldConfs)) {
  75. return toArray(arr).sort(handleSort)
  76. }
  77. var compares
  78. var list = map(arr, function (item) {
  79. return { data: item }
  80. })
  81. var sortConfs = getSortConfs(arr, list, fieldConfs, context)
  82. var len = sortConfs.length - 1
  83. while (len >= 0) {
  84. compares = buildMultiOrders(len, sortConfs[len], compares)
  85. len--
  86. }
  87. if (compares) {
  88. list = list.sort(compares)
  89. }
  90. return map(list, property('data'))
  91. }
  92. return []
  93. }
  94. module.exports = orderBy