compare-builder
v1.0.0
Published
Builds compare functions to make Sorting easier
Downloads
3
Maintainers
Readme
Compare Builder
A series of Tools to make sorting Arrays easier to work with, particularly when sorting objects.
Can be used to build compare functions to pass to Array.sort()
,
or can extend Array
directly to include new methods Array.sortByAsc()
, Array.sortByDesc()
and Array.buildSort().asc().desc().sort()
Example - Sorting Primitives
// sorting Primitives
const primitiveInput = ["1", "3", "2"]
// using Array Extensions
primitiveInput.sortByAsc() // ["1", "2", "3"]
primitiveInput.sortByDesc() // ["3", "2", "1"]
// using Comparators
primitiveInput.sort(byAttributeAsc(i => i)) // ["1", "2", "3"]
primitiveInput.sort(byAttributeDesc(i => i)) // ["3", "2", "1"]
Example - Sorting Objects
// Sorting Objects
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
// using Array Extensions
objectInput.sortByAsc(obj => obj.id) // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
objectInput.sortByDesc(obj => obj.id) // [{id: "3", foo: "a"}, {id: "2", foo: "b"}, {id: "1", foo: "c"}]
objectInput.buildSort()
.asc(obj => obj.id)
.desc(obj => obj.foo)
.sort() // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
// using Comparators
objectInput.sort(byAttributeAsc(obj => obj.id)) // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
objectInput.sort(byAttributeDesc(obj => obj.id)) // [{id: "3", foo: "a"}, {id: "2", foo: "b"}, {id: "1", foo: "c"}]
objectInput.sort(
new CompareBuilder()
.asc(obj => obj.id)
.desc(obj => obj.foo)
.build() // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
)
Installation
npm install --save compare-builder
Documentation
Extending Array
with sortByAsc() / sortByDesc() / buildSort()
To add the sortByAsc() / sortByDesc() / buildSort()
methods to JS's base Array
interface, you can import the
extension by including:
import "compare-builder/extend-array-with-sort-by"
into your codebase at some point before attempting to call [].sortByAsc()
// somewhere in your initialization logic
import "compare-builder/extend-array-with-sort-by"
// ...
// Array now has a sortByAsc() method
const result = ["1", "3", "2"].sortByAsc() // ["1", "2", "3"]
Sorting by extracted Attributes
Every method in this module relies on using an Attribute Extractor to choose the attribute to sort the items in the Array by.
Items are sorted using the native Javascript behaviour for the >
and <
operators.
So if an attribute is extracted that does not interact in a consistent way with the >
and <
operators, the
resulting sort will be inconsistent.
The recommendation is to use the Attribute Extractor to sort by a Primitive type, probably a string
or number
.
Function: Array.sortByAsc()
Definition: <T, R> (attributeExtractor?:AttributeExtractor<T, R>) => Array<T>
Extension on the Array
interface.
sortByAsc()
takes an optional Attribute Extractor function and sorts the Array
in ascending order using the output of the Attribute Extractor for sorting.
Items are sorted in place, consistent with the current Array.sort()
behaviour.
const primitiveInput = ["1", "3", "2"]
primitiveInput.sortByAsc() // ["1", "2", "3"]
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
objectInput.sortByAsc(obj => obj.id) // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
Function: Array.sortByDesc()
Definition: <T, R> (attributeExtractor?:AttributeExtractor<T, R>) => Array<T>
Extension on the Array
interface.
sortByDesc()
takes an optional Attribute Extractor function and sorts the Array
in descending order using the output of the Attribute Extractor for sorting.
Items are sorted in place, consistent with the current Array.sort()
behaviour.
const primitiveInput = ["1", "3", "2"]
primitiveInput.sortByDesc() // ["3", "2", "1"]
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
objectInput.sortByDesc(obj => obj.id) // [{id: "3", foo: "a"}, {id: "2", foo: "b"}, {id: "1", foo: "c"}]
Function: Array.buildSort()
Definition: <T> buildSort: () => ArraySorter<T>
Extension to the Array
interface.
buildSort()
returns an ArraySorter
which allows the sorting of an Array
to be more finely controlled, sorting in
multiple directions by different attributes.
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
objectInput.buildSort()
.asc(obj => obj.id)
.desc(obj => obj.foo)
.sort() // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
See the documentation on ArraySorter
for more information on how it works.
Class: new ArraySorter()
Definition:
interface ArraySorter<T> {
constructor(arrayToSort:Array<T>): ArraySorter<T>
asc<R>(attributeExtractor:AttributeExtractor<T, R>): ArraySorter<T>,
desc<R>(attributeExtractor:AttributeExtractor<T, R>): ArraySorter<T>,
sort(): Array<T>,
toSorted(): Array<T>
}
A class for sorting an Array based on different Comparators.
It takes an input Array in it's constructor, then a series of Comparators are configured using the asc() / desc()
methods,
then the input Array is sorted using these Comparators using the sort() / toSorted()
methods.
This class works in a similar way to CompareBuilder
but instead of returning the Comparator, it sorts the Array directly.
constructor()
- Takes an input Array that will be sorted
asc()
- Adds a sort by Ascending Comparator
desc()
- Adds a sort by Descending Comparator
sort()
- Combines the Comparators, sorts the Array in place, according to the Comparators, and returns the Array
toSorted()
- Combines the Comparators, makes a shallow copy and sorts the Array, according to the Comparators,
and returns the Array
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
new ArraySorter(objectInput)
.asc(obj => obj.id)
.desc(obj => obj.foo)
.sort() // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
Function: byAttributeAsc()
Definition: <T, R>(attributeExtractor:AttributeExtractor<T, R>) => Comparator<T>
Function that takes an Attribute Extractor and returns a Comparator that can be used in Array.sort()
.
The Comparator will sort the Array by the extracted attribute in ascending order.
const primitiveInput = ["1", "3", "2"]
primitiveInput.sort(byAttributeAsc(i => i)) // ["1", "2", "3"]
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
objectInput.sort(byAttributeAsc(obj => obj.id)) // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
Function: byAttributeDesc()
Definition: <T, R>(attributeExtractor:AttributeExtractor<T, R>) => Comparator<T>
Function that takes an Attribute Extractor and returns a Comparator that can be used in Array.sort()
.
The Comparator will sort the Array by the extracted attribute in descending order.
const primitiveInput = ["1", "3", "2"]
primitiveInput.sort(byAttributeDesc(i => i)) // ["3", "2", "1"]
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
objectInput.sort(byAttributeDesc(obj => obj.id)) // [{id: "3", foo: "a"}, {id: "2", foo: "b"}, {id: "1", foo: "c"}]
Function: combine()
Definition: <T>(...comparators:Array<Comparator<T>>) => Comparator<T>
Function that takes several Comparators and combines them to produce a new Comparator that sorts in the order of the input Comparators.
This allows Comparators to be combined to sort by one attribute, then a second, then a third.
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
objectInput.sort(
combine(
byAttributeAsc(obj => obj.id),
byAttributeDesc(obj => obj.foo)
)
) // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
Class: new CompareBuilder()
Definition:
interface CompareBuilder<T> {
constructor(): CompareBuilder<T>
asc<R>(attributeExtractor: AttributeExtractor<T, R>): CompareBuilder<T>,
desc<R>(attributeExtractor: AttributeExtractor<T, R>): CompareBuilder<T>,
build(): Comparator<T>
}
A builder class for constructing a Comparator from multiple different Attribute Extractors.
It is a potentially more convenient option than using combine()
with byAttributeAsc() / byAttributeDesc()
directly.
asc()
- Adds a sort by Ascending comparator
desc()
- Adds a sort by Descending comparator
build()
- Combines the Comparators and returns the combined Comparator
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
objectInput.sort(
new CompareBuilder()
.asc(obj => obj.id)
.desc(obj => obj.foo)
.build()
) // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
Function: sortByAsc()
Definition: <T, R>(attributeExtractor:AttributeExtractor<T, R>) => CompareBuilder<T>
A convenience method to make calling CompareBuilder
easier to use.
It is equivalent to calling:
new CompareBuilder().asc(attributeExtractor)
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
objectInput.sort(
sortByAsc(obj => obj.id)
.desc(obj => obj.foo)
.build()
) // [{id: "1", foo: "c"}, {id: "2", foo: "b"}, {id: "3", foo: "a"}]
Function: sortByDesc()
Definition: <T, R>(attributeExtractor:AttributeExtractor<T, R>) => CompareBuilder<T>
A convenience method to make calling CompareBuilder
easier to use.
It is equivalent to calling:
new CompareBuilder().desc(attributeExtractor)
const objectInput = [{id: "1", foo: "c"}, {id: "3", foo: "a"}, {id: "2", foo: "b"}]
objectInput.sort(
sortByDesc(obj => obj.id)
.asc(obj => obj.foo)
.build()
) // [{id: "3", foo: "a"}, {id: "2", foo: "b"}, {id: "1", foo: "c"}]