@@ -90,54 +90,67 @@ module.exports = sortBy
90
90
* }
91
91
* ```
92
92
*/
93
- function sortBy ( recordset , sortBy , sortTypes , sharedComputedProps , sharedCustomOrders ) {
94
- // First stage preformatting
93
+ function sortBy ( recordset , sortBy , sortTypes , namedConfigs ) {
94
+ // First stage data preparation
95
95
recordset = arrayify ( recordset )
96
96
sortBy = arrayify ( sortBy )
97
97
sortTypes = arrayify ( sortTypes )
98
- sharedComputedProps = t . isObject ( sharedComputedProps ) ? sharedComputedProps : { }
99
- sharedCustomOrders = t . isObject ( sharedCustomOrders ) ? sharedCustomOrders : { }
100
-
98
+
99
+ let namedComputedProps = { }
100
+ let namedCustomOrders = { }
101
+ if ( t . isObject ( namedConfigs ) ) {
102
+ if ( t . isDefined ( namedConfigs [ 'namedComputedProps' ] ) ) {
103
+ namedComputedProps = namedConfigs [ 'namedComputedProps' ]
104
+ }
105
+ if ( t . isDefined ( namedConfigs [ 'namedCustomOrders' ] ) ) {
106
+ namedCustomOrders = namedConfigs [ 'namedCustomOrders' ]
107
+ }
108
+ }
109
+
101
110
// Perform sanity checks.
102
111
let isPrimitiveSort = recordset . some ( record => t . isPrimitive ( record ) )
103
112
if ( isPrimitiveSort ) {
104
- // Any 'sortBy' arguments invalidate the sort, because they will not be
105
- // applicable on a primitive array.
106
- if ( sortBy . length !== 0 ) {
107
- return recordset
113
+ // The only applicable 'sortBy' arguments on a primitive array
114
+ // are 'computed property' functions.
115
+ for ( let i = 0 ; i < sortBy . length ; i ++ ) {
116
+ if ( ! t . isFunction ( sortBy [ i ] ) ) {
117
+ return recordset
118
+ }
108
119
}
109
120
} else {
110
- // At least one 'sortBy' argument must be provided, so that the recordset
121
+ // At least one 'sortBy' argument must be provided, so that the recordset
111
122
// can be sorted according to that property.
112
123
if ( sortBy . length === 0 ) {
113
124
return recordset
114
125
}
115
126
}
116
-
117
- // Ensure that if sharedComputedProps is provided, that the object keys
127
+
128
+ // Ensure that if namedComputedProps is provided, that the object keys
118
129
// are referenced in the sortBy array
119
- if ( Object . keys ( sharedComputedProps ) . length > 0 ) {
120
- for ( let key in Object . keys ( sharedComputedProps ) ) {
121
- if ( ! t . isDefined ( sortBy [ key ] ) ) {
130
+ let noOfNamedComputedProps = Object . keys ( namedComputedProps ) . length
131
+ if ( noOfNamedComputedProps > 0 ) {
132
+ for ( let i = 0 ; i < noOfNamedComputedProps ; i ++ ) {
133
+ if ( sortBy . indexOf ( Object . keys ( namedComputedProps ) [ i ] ) < 0 ) {
122
134
// Missing object key, return the recordset unchanged
123
135
return recordset
124
136
}
125
137
}
126
138
}
127
-
128
- // Ensure that if sharedCustomOrders is provided, that the object keys
139
+
140
+ // Ensure that if namedCustomOrders is provided, that the object keys
129
141
// are referenced in the sortTypes array
130
- if ( Object . keys ( sharedCustomOrders ) . length > 0 ) {
131
- for ( let key in Object . keys ( sharedCustomOrders ) ) {
132
- if ( ! t . isDefined ( sortTypes [ key ] ) ) {
142
+ let noOfNamedCustomOrders = Object . keys ( namedCustomOrders ) . length
143
+ if ( noOfNamedCustomOrders > 0 ) {
144
+ for ( let i = 0 ; i < noOfNamedCustomOrders ; i ++ ) {
145
+ if ( sortTypes . indexOf ( Object . keys ( namedCustomOrders ) [ i ] ) < 0 ) {
133
146
// Missing object key, return the recordset unchanged
134
147
return recordset
135
148
}
136
149
}
137
150
}
138
-
139
- // Second stage preformatting . Ensure that each property in sortBy
140
- // has a corresponding property in sortTypes. Populate missing, and
151
+
152
+ // Second stage data preparation . Ensure that each property in sortBy
153
+ // has a corresponding property in sortTypes. Populate missing and
141
154
// remove excess, as required.
142
155
if ( ( sortBy . length === 0 ) && ( sortTypes . length === 0 ) ) {
143
156
sortTypes . push ( 'asc' )
@@ -148,69 +161,111 @@ function sortBy (recordset, sortBy, sortTypes, sharedComputedProps, sharedCustom
148
161
for ( let i = 0 ; i < noOfMissingSortTypes ; i ++ ) {
149
162
sortTypes . push ( 'asc' )
150
163
}
151
- } else if ( sortBy . length < sortTypes . length ) {
164
+ } else if ( ! isPrimitiveSort && ( sortBy . length < sortTypes . length ) ) {
152
165
// Too many sortTypes have been provided. Prune the redundant ones
153
166
// at the end of the sortType array.
154
167
sortTypes . splice ( - 1 , sortTypes . length - sortBy . length )
155
168
}
156
-
169
+
157
170
if ( isPrimitiveSort ) {
158
171
return recordset . sort ( comparePrim ( sortBy , sortTypes ) )
159
172
} else {
160
- return recordset . sort ( compare ( sortBy , sortTypes , sharedComputedProps , sharedCustomOrders ) )
173
+ return recordset . sort ( compare ( sortBy , sortTypes , namedComputedProps , namedCustomOrders ) )
161
174
}
162
175
}
163
176
164
- // @TODO : implement compare primitives
165
177
function comparePrim ( sortBy , sortTypes ) {
166
- console . log ( 'comparePrim() NOT YET IMPLEMENTED' )
178
+ // The property should be undefined or a function
179
+ let sorts = sortBy . slice ( 0 )
180
+ let property = sorts . shift ( )
181
+
182
+ // The sort should be 'asc', 'desc', or a custom array
183
+ let sort
184
+ if ( sortTypes . length > 1 ) {
185
+ sort = sortTypes . slice ( 0 )
186
+ } else {
187
+ let types = sortTypes . slice ( 0 )
188
+ sort = types . shift ( )
189
+ }
190
+
191
+ return function sorter ( a , b ) {
192
+ let x
193
+ let y
194
+ let result
195
+
196
+ // Allocate the comparees.
197
+ if ( t . isFunction ( property ) ) {
198
+ x = property ( a )
199
+ y = property ( b )
200
+ } else {
201
+ x = a
202
+ y = b
203
+ }
204
+
205
+ // Perform the sort
206
+ if ( t . isArrayLike ( sort ) ) {
207
+ // Apply custom ordering
208
+ result = sort . indexOf ( x ) - sort . indexOf ( y )
209
+ } else {
210
+ // Perform an asc sort by default, then invert later if a desc has been
211
+ // requested for the current property.
212
+ result = getAscOrder ( x , y )
213
+ }
214
+
215
+ // Present the result
216
+ if ( sort === 'desc' ) {
217
+ return result * - 1
218
+ } else {
219
+ return result
220
+ }
221
+ }
167
222
}
168
223
169
- function compare ( sortBy , sortTypes , sharedComputedProps , sharedCustomOrders ) {
224
+ function compare ( sortBy , sortTypes , namedComputedProps , namedCustomOrders ) {
170
225
// Identify the first property on which to sort, and the way it should be sorted.
171
-
226
+
172
227
// The property may be either a string property name, an anonymous function, or
173
- // a string key into the sharedComputedProps object.
228
+ // a string key into the namedComputedProps object.
174
229
let sorts = sortBy . slice ( 0 )
175
230
let property = sorts . shift ( )
176
-
177
- // The sort can be 'asc', 'desc', a custom array or a string key into the
178
- // sharedCustomOrders object.
231
+
232
+ // The sort can be 'asc', 'desc', a custom array or a string key into the
233
+ // namedCustomOrders object.
179
234
let types = sortTypes . slice ( 0 )
180
235
let sort = types . shift ( )
181
-
236
+
182
237
return function sorter ( a , b ) {
183
238
let x
184
239
let y
185
240
let result
186
241
let recurse
187
242
let currentSort = sort
188
-
243
+
189
244
// Allocate the comparees.
190
245
if ( t . isFunction ( property ) ) {
191
246
x = property ( a )
192
247
y = property ( b )
193
- } else if ( t . isDefined ( sharedComputedProps [ property ] ) ) {
194
- x = sharedComputedProps [ property ] ( a )
195
- y = sharedComputedProps [ property ] ( b )
248
+ } else if ( t . isDefined ( namedComputedProps [ property ] ) ) {
249
+ x = namedComputedProps [ property ] ( a )
250
+ y = namedComputedProps [ property ] ( b )
196
251
} else {
197
252
x = a [ property ]
198
253
y = b [ property ]
199
254
}
200
-
255
+
201
256
// Perform the sort
202
257
if ( t . isArrayLike ( sort ) ) {
203
258
// Apply custom ordering
204
259
result = sort . indexOf ( x ) - sort . indexOf ( y )
205
- } else if ( t . isDefined ( sharedCustomOrders [ sort ] ) ) {
260
+ } else if ( t . isDefined ( namedCustomOrders [ sort ] ) ) {
206
261
// Apply custom ordering
207
- result = sharedCustomOrders [ sort ] . indexOf ( x ) - sharedCustomOrders [ sort ] . indexOf ( y )
262
+ result = namedCustomOrders [ sort ] . indexOf ( x ) - namedCustomOrders [ sort ] . indexOf ( y )
208
263
} else {
209
- // Perform an asc sort by default, then invert later if a desc has been
264
+ // Perform an asc sort by default, then invert later if a desc has been
210
265
// requested for the current property.
211
266
result = getAscOrder ( x , y )
212
267
}
213
-
268
+
214
269
// Reset this sorting function and parent, unless there is an equal
215
270
// result and there are more sorts still to perform, in which case
216
271
// move on to the next one.
@@ -235,7 +290,7 @@ function compare (sortBy, sortTypes, sharedComputedProps, sharedCustomOrders) {
235
290
}
236
291
}
237
292
238
- function getAscOrder ( x , y ) {
293
+ function getAscOrder ( x , y ) {
239
294
let result
240
295
if ( x === null && y === null ) {
241
296
result = 0
0 commit comments