UNPKG

@romanhavryliv/deep-sorting

Version:

Sorting function for arrays of objects.

140 lines (98 loc) 4.55 kB
# 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