npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

compare-builder

v1.0.0

Published

Builds compare functions to make Sorting easier

Downloads

3

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"}]