UNPKG

3.31 kBJavaScriptView Raw
1'use strict'
2
3const size = require('../../utils/array').size
4
5function factory (type, config, load, typed) {
6 const matrix = load(require('../../type/matrix/function/matrix'))
7 const compareAsc = load(require('../relational/compare'))
8 const compareDesc = function (a, b) {
9 return -compareAsc(a, b)
10 }
11 const compareNatural = load(require('../relational/compareNatural'))
12
13 /**
14 * Sort the items in a matrix.
15 *
16 * Syntax:
17 *
18 * math.sort(x)
19 * math.sort(x, compare)
20 *
21 * Examples:
22 *
23 * math.sort([5, 10, 1]) // returns [1, 5, 10]
24 * math.sort(['C', 'B', 'A', 'D'], math.compareNatural)
25 * // returns ['A', 'B', 'C', 'D']
26 *
27 * function sortByLength (a, b) {
28 * return a.length - b.length
29 * }
30 * math.sort(['Langdon', 'Tom', 'Sara'], sortByLength)
31 * // returns ['Tom', 'Sara', 'Langdon']
32 *
33 * See also:
34 *
35 * filter, forEach, map, compare, compareNatural
36 *
37 * @param {Matrix | Array} x A one dimensional matrix or array to sort
38 * @param {Function | 'asc' | 'desc' | 'natural'} [compare='asc']
39 * An optional _comparator function or name. The function is called as
40 * `compare(a, b)`, and must return 1 when a > b, -1 when a < b,
41 * and 0 when a == b.
42 * @return {Matrix | Array} Returns the sorted matrix.
43 */
44 const sort = typed('sort', {
45 'Array': function (x) {
46 _arrayIsVector(x)
47 return x.sort(compareAsc)
48 },
49
50 'Matrix': function (x) {
51 _matrixIsVector(x)
52 return matrix(x.toArray().sort(compareAsc), x.storage())
53 },
54
55 'Array, function': function (x, _comparator) {
56 _arrayIsVector(x)
57 return x.sort(_comparator)
58 },
59
60 'Matrix, function': function (x, _comparator) {
61 _matrixIsVector(x)
62 return matrix(x.toArray().sort(_comparator), x.storage())
63 },
64
65 'Array, string': function (x, order) {
66 _arrayIsVector(x)
67 return x.sort(_comparator(order))
68 },
69
70 'Matrix, string': function (x, order) {
71 _matrixIsVector(x)
72 return matrix(x.toArray().sort(_comparator(order)), x.storage())
73 }
74 })
75
76 sort.toTex = undefined // use default template
77
78 /**
79 * Get the comparator for given order ('asc', 'desc', 'natural')
80 * @param {'asc' | 'desc' | 'natural'} order
81 * @return {Function} Returns a _comparator function
82 */
83 function _comparator (order) {
84 if (order === 'asc') {
85 return compareAsc
86 } else if (order === 'desc') {
87 return compareDesc
88 } else if (order === 'natural') {
89 return compareNatural
90 } else {
91 throw new Error('String "asc", "desc", or "natural" expected')
92 }
93 }
94
95 /**
96 * Validate whether an array is one dimensional
97 * Throws an error when this is not the case
98 * @param {Array} array
99 * @private
100 */
101 function _arrayIsVector (array) {
102 if (size(array).length !== 1) {
103 throw new Error('One dimensional array expected')
104 }
105 }
106
107 /**
108 * Validate whether a matrix is one dimensional
109 * Throws an error when this is not the case
110 * @param {Matrix} matrix
111 * @private
112 */
113 function _matrixIsVector (matrix) {
114 if (matrix.size().length !== 1) {
115 throw new Error('One dimensional matrix expected')
116 }
117 }
118
119 return sort
120}
121
122exports.name = 'sort'
123exports.factory = factory