1.1.1 • Published 1 year ago

@romanhavryliv/deep-sorting v1.1.1

Weekly downloads
73
License
MIT
Repository
github
Last release
1 year ago

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

NameHistory marks number
Adam8
Adam7
Adam5
Bob7
Eric8

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

NameHistory marks number
Adam8
Eric8
Adam7
Bob7
Adam5

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']]:

NameHistory marks number
Eric8
Adam8
Bob7
Adam7
Adam5

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
1.1.1

1 year ago

1.1.0

1 year ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago