Wondering what’s next for npm?Check out our public roadmap! »

    @bemoje/arr-sort

    1.0.2 • Public • Published

    @bemoje/arr-sort

    Sort an array considerably faster than the native Array.prototype.sort as a drop-in replacement. Fork of of the famous timsort module, but this module allows for passing comparator-builder options instead of a comparator function. In short, advanced comparators made easy. Timsort: https://www.npmjs.com/package/timsort

    Version

    NPM version

    Travis CI

    dependencies

    Dependencies

    dependencies

    Stats

    NPM downloads Forks

    Donate

    Buy Me A Beer donate button PayPal donate button

    Installation

    npm install @bemoje/arr-sort
    npm install --save @bemoje/arr-sort
    npm install --save-dev @bemoje/arr-sort

    Usage

     
    import arrSort from '@bemoje/arr-sort'
     
    /**
     * OPTIONAL: REPLACE native Array.prototype.sort
     *
     * instead of calling sort(arr, options), you can also use arr.sort(options).
     *
     * It's generally not recommended to replace native class prototype methods, but since timsort is sturdy, tested and tried and proven to be considerably faster and IS truly a drop-in replacement, this might be a case where it could be considered a viable option.
     *
     * To activate this, do:
     */
     
    arrSort.replaceNative()
     
    /**
     * DATA: STRINGS
     * --------------
     */
     
    let arr = ['5', '2', '4', '30', '1', '3']
     
    /**
     * SORT ALPHABETICALLY BY DEFAULT
     * ------------------------------
     */
     
    arrSort(arr)
    //=> ['1', '2', '3', '30', '4', '5']
     
    // OR
    arr.sort()
    //=> ['1', '2', '3', '30', '4', '5']
     
    /**
     * DATA: NUMERIC VALUES
     * ----------------------
     */
     
    arr = [5, 2, 4, 30, 1, 3]
     
    /**
     * SORT NUMERICALLY
     * ----------------
     */
     
    arrSort(arr, {
      numeric: true,
    })
    //=> [1, 2, 3, 4, 5, 30]
     
    /**
     * SORT DESCENDING
     * ---------------
     */
     
    arrSort(arr, {
      numeric: true,
      descending: true,
    })
    //=> [30, 5, 4, 3, 2, 1]
     
    /**
     * DATA: PERSON OBJECTS
     * --------------------
     */
     
    arr = [
      { name: 'john', age: 4 },
      { name: 'bill', age: 8 },
    ]
     
    /**
     * SORT OBJECTS BY PROPERTY
     * ------------------------
     */
     
    arrSort(arr, {
      by: 'name',
    })
     
    /* =>
      [
        { name: 'bill', age: 8 },
        { name: 'john', age: 4 },
      ]
    */
     
    arrSort(arr, {
      numeric: true,
      by: 'age',
    })
     
    /* =>
      [
        { name: 'john', age: 4 },
        { name: 'bill', age: 8 },
      ]
    */
     
    /**
     * DATA: PERSON OBJECTS WITH NESTED NAME OBJECTS
     * ---------------------------------------------
     */
     
    arr = [
      { id: 0, name: { first: 'snoop', last: 'doggy' } },
      { id: 1, name: { first: 'kurt', last: 'qobain' } },
    ]
     
    /**
     * SORT OBJECTS BY NESTED PROPERTY WITH DOT NOTATION
     * -------------------------------------------------
     */
     
    arrSort(arr, {
      by: 'name.first',
    })
     
    /* =>
      [
        { id: 1, name: { first: 'kurt', last: 'qobain' } },
        { id: 0, name: { first: 'snoop', last: 'doggy' } },
      ]
    */
     
    arrSort(arr, {
      by: 'name.last',
    })
     
    /* =>
      [
        { id: 0, name: { first: 'snoop', last: 'doggy' } },
        { id: 1, name: { first: 'kurt', last: 'qobain' } },
      ]
    */
     
    /**
     * DATA: STRING DIRECTORY PATHS SPLIT IN ARRAYS
     * --------------------------------------------
     */
     
    arr = [
      ['repo', 'src', 'compare.js'],
      ['repo', 'docs', 'index.html'],
    ]
     
    /**
     * SORT BY ARRAY INDEX
     * -------------------
     */
     
    arrSort(arr, {
      by: 2,
    })
     
    /* =>
      [
        ['repo', 'src', 'compare.js'],
        ['repo', 'docs', 'index.html'],
      ]
    */
     
    arrSort(arr, {
      by: 1,
    })
     
    /* =>
      [
        ['repo', 'docs', 'index.html' ],
        ['repo', 'src', 'compare.js'],
      ]
    */
     
    /**
     * DATA: DIRECTORY PATHS ARRAYS WITH SUB-ARRAYS
     * --------------------------------------------
     */
     
    arr = [
      ['repo', 'src', ['compare', 'json']],
      ['repo', 'src', ['compare', 'ts']],
      ['repo', 'src', ['compare', 'js']],
    ]
     
    /**
     * SORT ARRAYS AND SUB-ARRAYS RECURSIVELY
     * ------------------------------------
     */
     
    arrSort(arr, {
      arrays: true,
    })
     
    /* =>
      [
        ['repo', 'src', ['compare', 'js']],
        ['repo', 'src', ['compare', 'json']],
        ['repo', 'src', ['compare', 'ts']],
      ]
    */
     
    /**
     * DATA: IP ADDRESSES AS ARRAYS
     * ----------------------------
     */
     
    arr = [
      [192, 168, 0, 1],
      [192, 168, 0, 101],
      [172, 0, 0, 1],
    ]
     
    /**
     * SORT NUMERIC IP-ADDRESSES AS ARRAYS
     * -----------------------------------
     */
     
    arrSort(arr, {
      numeric: true,
      arrays: true,
    })
     
    /* =>
      [
        [172, 0, 0, 1],
        [192, 168, 0, 1],
        [192, 168, 0, 101],
      ]
    */
     
    /**
     * DATA: USER CLASS INSTANCES
     * --------------------------
     */
     
    class User {
      constructor(firstName, lastName) {
        this.firstName = firstName
        this.lastName = lastName
      }
      get fullName() {
        return this.firstName + ' ' + this.lastName
      }
    }
     
    arr = [
      new User('john', 'doe'),
      new User('peter', 'wick'),
      new User('peter', 'johnson'),
      new User('les', 'paul'),
    ]
     
    /**
     * SORT BY GETTER-FUNCTION
     * ------------------------
     */
     
    arrSort(arr, {
      by: (user) => {
        return user.fullName
      },
    })
     
    /* =>
      [
        { firstName: 'john', lastName: 'doe'},
        { firstName: 'les', lastName: 'paul'},
        { firstName: 'peter', lastName: 'johnson'},
        { firstName: 'peter', lastName: 'wick'},
      ]
    */
     

    Benchmark

    Note: For short arrays, the speedup is insignificant or about the same. The more data there is, the faster the algorithms of timsort become, proportionally. Although timsort is a bit slower for short arrays, we're talking about a few milliseconds. So the overall improvement from Array.prototype.sort is quite unquestionable, imo.

    ArrayType Length arrSort Array.prototype.sort Times faster
    randomInt 10 715 954 1.33
    randomInt 100 6878 14034 2.04
    randomInt 1000 104597 210992 2.02
    randomInt 10000 1560955 2804903 1.80
    descendingInt 10 571 389 0.68
    descendingInt 100 1122 1971 1.76
    descendingInt 1000 4946 17183 3.47
    descendingInt 10000 43319 170926 3.95
    ascendingInt 10 534 369 0.69
    ascendingInt 100 1022 1842 1.80
    ascendingInt 1000 4460 16485 3.70
    ascendingInt 10000 36601 157912 4.31
    ascending3RandomExchangesInt 10 649 541 0.83
    ascending3RandomExchangesInt 100 1757 3817 2.17
    ascending3RandomExchangesInt 1000 6584 18115 2.75
    ascending3RandomExchangesInt 10000 46194 172214 3.73
    ascending10RandomEndInt 10 792 750 0.95
    ascending10RandomEndInt 100 2430 3578 1.47
    ascending10RandomEndInt 1000 8165 19885 2.44
    ascending10RandomEndInt 10000 50357 176797 3.51
    allEqualInt 10 526 397 0.75
    allEqualInt 100 1048 1949 1.86
    allEqualInt 1000 4400 16789 3.82
    allEqualInt 10000 35976 162857 4.53
    manyDuplicateInt 10 833 770 0.92
    manyDuplicateInt 100 7806 11705 1.50
    manyDuplicateInt 1000 110968 173539 1.56
    manyDuplicateInt 10000 1491473 2255993 1.51
    someDuplicateInt 10 797 747 0.94
    someDuplicateInt 100 7797 11712 1.50
    someDuplicateInt 1000 112189 174973 1.56
    someDuplicateInt 10000 1526839 2301187 1.51

    Tests

    Uses Jest to test module functionality. Run tests to get coverage details.

    npm run test

    API

    Table of Contents

    arrSort

    Sort an array considerably faster than the native Array.prototype.sort as a drop-in replacement. Fork of of the famous timsort module, but this module allows for passing comparator-builder options instead of a comparator function. In short, advanced comparators made easy. Timsort: https://www.npmjs.com/package/timsort

    Parameters
    • arr Array The array to sort.

    • compare (function | object)? Comparator function or comparator-builder options. Defaults to alphabetical compararison.

      • compare.numeric boolean Sort numerically. Defaults to lexicographic/alphabetic sort. (optional, default false)

      • compare.descending boolean Sort in descending order. Defaults to ascending order. (optional, default false)

      • compare.array boolean Sort arrays. Nested arrays are also compared recursively. (optional, default false)

      • compare.by (number | string | getter) Sort by either array index, a callback(element): any - or by object keys with dot-notation support. (optional, default undefined)

    • lo number? First element in the range (inclusive).

    • hi number? Last element in the range.

    Returns Array The sorted array

    replaceNative

    Replace the native Array.prototype.sort method with arrSort.

    Returns void

    getter

    Callback type definition.

    Type: Function

    Parameters
    • a any The value

    Returns any The value to be compared

    Install

    npm i @bemoje/arr-sort

    DownloadsWeekly Downloads

    18

    Version

    1.0.2

    License

    MIT

    Unpacked Size

    55.7 kB

    Total Files

    5

    Last publish

    Collaborators

    • avatar