@romanhavryliv/deep-sorting
v1.1.1
Published
Sorting function for arrays of objects.
Downloads
241
Readme
Deep Sorting
Sorting function for arrays of objects.
install
npm install @romanhavryliv/deep-sorting
usage
import deepSorting from '@romanhavryliv/deep-sorting';
...
deepSorting(arrayToSort, arrayOfSortingCriteria)
arrayToSort
- an array that needs to be sorted (is sorted in place).arrayOfSortingCriteria
- an array of sorting criteria. Criteria can be a string, a function or an array of two elements where the first one is criteria itself (a string or a function) and the second one is descendic pointer. This "descendic pointer" points to sort the array by this particular criteria using descendic order. "Descendic" pointer should be only "desc" string. Any other value is ignored. The order of criteria in array is important for sorting order.
examples
For example we have a database of pupils as an array of objects pupils = [pupil1, pupil2, pupil3, ...]
.
And we have next structure of our objects (pupil1, pupil2, pupil3, ...):
{
name: {
firstName,
lastName,
},
marks: {
history, // e.g. [A, A, B, D, A],
arts, // e.g. [A, A, A],
},
}
String sorting criteria is a path in pupil object to the primitive that must be compared for sorting. String criteria can begin either with "." (period) or without it. '.name.firstName'
and 'name.firstName'
are equal.
Also it can start with "[" (opening square bracket)
`[${name}].firstName`
If we want to sort pupils by name we should write next '.name.firstName'
.
And our arrayOfSortingCriteria
would look like next
arrayOfSortingCriteria = ['.name.firstName']
.
Or with descendic order:
arrayOfSortingCriteria = [['.name.firstName', 'desc']]
.
Function sorting criteria is a function that return some primitive that can be compared for sorting. If we want to sort pupils by number of marks in History we should create next function
const historyMarksNumber = (pupil) => pupil.marks.history.length;
or with descendic order:
const historyMarksNumber = (pupil) => [pupil.marks.history.length, 'desc'];
and arrayOfSortingCriteria = [historyMarksNumber]
.
What is the purpose of DEEP sorting?
According to examples above we can combine those sorting methods.
If we pass next
arrayOfSortingCriteria = ['.name.firstName', historyMarksNumber]
we can have such result as
| Name | History marks number | | ---- | -------------------- | | Adam | 8 | | Adam | 7 | | Adam | 5 | | Bob | 7 | | Eric | 8 |
Here we have three pupils with name Adam and they are sorted by "History marks number" as well.
Order of criteria in array is important for sorting order!
For replaced criteria
arrayOfSortingCriteria = [historyMarksNumber, '.name.firstName']
result is
| Name | History marks number | | ---- | -------------------- | | Adam | 8 | | Eric | 8 | | Adam | 7 | | Bob | 7 | | Adam | 5 |
Now we have two pupils with "History marks number" of "8" and two of "7" and they are sorted by "firstName" as well (inside of mark "8" and "7").
Let's see the second table with descendic order for the second criteria
arrayOfSortingCriteria = [historyMarksNumber, ['.name.firstName', 'desc']]
:
| Name | History marks number | | ---- | -------------------- | | Eric | 8 | | Adam | 8 | | Bob | 7 | | Adam | 7 | | Adam | 5 |
Now we have descendic order of pupils by their firstName inside the list with the same "History marks number".
Object complexity
The object (pupil) can be of any level of complexity combining objects and arrays inside.
Few more examples for string criteria:
'.marks.arts[1]' - to sort pupils by "second mark of Arts".
`.marks[${subject}][1]` - to sort pupils by second mark of a "subject" passed as variable.
Function complexity depends only on your needs. The only thing it must do - return a primitive for sorting comparison.
arrayOfSortingCriteria
can contain only strings, only functions or any combination of those.
If an empty array is passed as arrayOfSortingCriteria
then regular sorting is applied (it doesn't change anything in array of objects).
Change log (to v 1.1.x)
- fixed leading period issue
- added descentic order of sorting
- added typescript