Coder Social home page Coder Social logo

yobacca / natural-orderby Goto Github PK

View Code? Open in Web Editor NEW
53.0 2.0 9.0 578 KB

Lightweight (< 1.6kB gzipped) and performant natural sorting of arrays and collections by differentiating between unicode characters, numbers, dates, etc.

License: MIT License

JavaScript 2.43% Shell 0.07% TypeScript 97.50%
natural-sort human sort order natsort compare

natural-orderby's People

Contributors

mjomble avatar renovate[bot] avatar thomasdenh avatar yobacca avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

natural-orderby's Issues

"2019-12-30" and "12/30/2019" parsed as different dates

I had an issue where "2019-12-30" and "12/30/2019" were not comparing as equal. While I recognize this is really an issue with JavaScript, it might make sense for a sort of work-around to be available in the library.

From Firefox:

image

node engine in package.json not necessary, causes problems with yarn install

When I try to install this package using yarn via yarn add, on a system running Node v6.x, the installation fails.

In this module's package.json file, there is an entry for the node engine:

  "engines": {
    "node": "^8.10.0 || >=9.10.0"
  },

Most npm packages that don't have direct dependencies on any node features and they usually don't specify a node version requirement, and use this:

  "engines": {
    "node": "*"
  },

We are using yarn for our node package manager, and it appears that yarn pays attention to this engine property, and compares it to the active node version. So, this means that if I'm running Node v6.x, I can't install natural-orderby, because it specifies Node v >8.10 -- even though it doesn't require node.

This should be changed in the npm package's package.json, to:

  "engines": {
    "node": "*"
  },

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Warning

These dependencies are deprecated:

Datasource Name Replacement PR?
npm babel-eslint Available
npm eslint-plugin-node Available

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • chore(deps): replace dependency eslint-plugin-node with eslint-plugin-n ^14.0.0
  • chore(deps): update dependency @rollup/plugin-node-resolve to v15.2.3
  • chore(deps): update dependency eslint to v8.57.0
  • chore(deps): update dependency eslint-config-prettier to v8.10.0
  • chore(deps): update dependency eslint-plugin-import to v2.29.1
  • chore(deps): update dependency eslint-plugin-jest to v27.9.0
  • chore(deps): update dependency lint-staged to v13.3.0
  • chore(deps): update dependency prettier to v2.8.8
  • chore(deps): update dependency rollup-plugin-dts to v5.3.1
  • chore(deps): update dependency typescript to v4.9.5
  • chore(deps): update typescript-eslint monorepo to v5.62.0 (@typescript-eslint/eslint-plugin, @typescript-eslint/parser)
  • chore(deps): update actions/checkout action to v4
  • chore(deps): update actions/setup-node action to v4
  • chore(deps): update commitlint monorepo to v19 (major) (@commitlint/cli, @commitlint/config-conventional, @commitlint/types)
  • chore(deps): update dependency eslint to v9
  • chore(deps): update dependency eslint-config-prettier to v9
  • chore(deps): update dependency eslint-plugin-jest to v28
  • chore(deps): update dependency eslint-plugin-prettier to v5
  • chore(deps): update dependency husky to v9
  • chore(deps): update dependency lint-staged to v15
  • chore(deps): update dependency prettier to v3
  • chore(deps): update dependency rollup to v4
  • chore(deps): update dependency rollup-plugin-dts to v6
  • chore(deps): update dependency typescript to v5
  • chore(deps): update typescript-eslint monorepo to v8 (major) (@typescript-eslint/eslint-plugin, @typescript-eslint/parser)
  • 🔐 Create all rate-limited PRs at once 🔐

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/test.yml
  • actions/checkout v3
  • actions/setup-node v3
npm
package.json
  • @ampproject/filesize ^4.3.0
  • @babel/core ^7.18.2
  • @babel/preset-env ^7.18.2
  • @babel/preset-modules ^0.1.5
  • @babel/preset-typescript ^7.17.12
  • @changesets/cli ^2.25.2
  • @commitlint/cli ^17.2.0
  • @commitlint/config-conventional ^17.2.0
  • @commitlint/types ^17.0.0
  • @rollup/plugin-babel ^6.0.0
  • @rollup/plugin-node-resolve ^15.0.1
  • @rollup/plugin-terser ^0.3.0
  • @types/jest 29.2.6
  • @typescript-eslint/eslint-plugin ^5.42.1
  • @typescript-eslint/parser ^5.42.1
  • babel-eslint ^10.1.0
  • babel-jest ^29.3.1
  • cross-env ^7.0.3
  • docsify-cli ^4.3.0
  • eslint ^8.27.0
  • eslint-config-prettier ^8.5.0
  • eslint-plugin-import ^2.23.4
  • eslint-plugin-jest ^27.1.4
  • eslint-plugin-node ^11.1.0
  • eslint-plugin-prettier ^4.0.0
  • husky ^8.0.0
  • jest ^29.3.1
  • lint-staged ^13.0.3
  • prettier ^2.5.1
  • rollup ^2.79.1
  • rollup-plugin-delete ^2.0.0
  • rollup-plugin-dts ^5.0.0
  • ts-jest ^29.0.3
  • typescript ^4.7.3
  • node >=18
travis
.travis.yml
  • node 8

  • Check this box to trigger a request for Renovate to run again on this repository

Incorrect Sorting

I haven't dove into it too much, but in a specific case I noticed it doesn't appear to be sorting as intended.

var naturalOrderby = require("natural-orderby")

var items = ['A110', 'A100', 'A090', 'A200', 'A50'];
naturalOrderby.orderBy(items);

Result

["A50", "A100", "A110", "A200", "A090"]

https://runkit.com/embed/fxldnunwae3g

It's putting 090 at the end. If you remove the A it works as expected.

Sort difference with similar library.

Library returns the following sort: ["00A", "00aa", "000A"]. However, a similar library for server side (Python) returns ["00A", "000A", "00aa"]. Which one is right? What is used to decide the difference?

"2-020-00" treated as a Date in Chrome, but not Firefox or Safari

I was using natural-orderby to try compare "2-020-00" and "3-000-00", and found that Firefox produced the expected ordering, while Chrome did not.

compare()("2-020-00", "3-000-00"); // 1 in Chrome, -1 in Firefox and Safari

I believe this is because Date.parse('2-020-00'); yields 951026400000 in Chrome, but NaN in Firefox and Safari.

I realize this is a browser difference that would be rather hard to fix. MDN even recommends against Date.parse for presumably that reason. But in case you had any ideas, I thought I'd post it here. :-D

Incorrect order with diacritics

The order is incorrect when the string contains diacritics

> orderBy(['b', 'd', 'f', 'A', 'C', 'E'])
[ 'A', 'C', 'E', 'b', 'd', 'f' ]
// correct

> orderBy(['b', 'd', 'f', 'A', 'Cé', 'E'])
[ 'A', 'b', 'Cé', 'E', 'd', 'f' ]
// incorrect

Execution time increases exponentially with the length of sorted string value

Tested environment:

  • Chromium 92/Firefox 90 on Ubuntu, Chrome on Mac (unsure of the versions)

Description

  • When sorting an array of objects (of any length), execution times when calling orderBy increase dramatically as the length of the string value being sorted increases.(Times will obviously vary from machine to machine, but I imagine the curve will look mostly the same anywhere)
    • Given a length of 20 characters, I see times around 0.2ms
    • 100 chars gives ~13ms
    • 200 chars gives ~210ms
    • 300 chars gives ~1000ms

Repro

  • I ran the code below in Chromium/Firefox, as well as RunJS to narrow down the issue, and the results were pretty consistent across environments
  • The value of label in this case is 200 characters in length, and can be changed to see different execution times
import { orderBy } from 'natural-orderby';

const inputArray = [
  {
        "label": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv",
        "value": "foo"
    }
];

const key = 'label';

const time0 = performance.now();

orderBy(inputArray, key);

const time1 = performance.now();

console.log(`call to orderBy took ${time1 - time0}ms`);

Output: 'call to orderBy took 204.47000000058324ms'

Other notes

  • Breaking up the string with hyphens or white space offsets the increase in execution time
  • The number of elements in the array has no significant impact on execution times, unless those items also have similar long unbroken string values

Dollar values not parsed as numbers

I'm not sure that this is a design goal, but I see that dollar values (and presumably other currencies) are not parsed to be identical to plain numbers.

const {compare} = require("natural-orderby")

console.log("strings and numbers", compare()("1.00", 1)); // 0
console.log("dollar-strings and numbers", compare()("$1.00", 1)); // 1

(See https://runkit.com/dahjelle/5dd552e003c3750014962150 for a runnable version of the above.)

I haven't dived in deep to see how the algorithm in this library works, but does it seem like this is a possible and desired feature?

Wrong sorting of names with suffixes

Given:

  • "2024-01-01"
  • "2024-05-01"
  • "2024-01-05"
  • "2024-01-05 Foo"

Expected order:

  • "2024-01-01"
  • "2024-01-05"
  • "2024-01-05 Foo"
  • "2024-05-01"

Output order of the package:

  • "2024-01-05 Foo"
  • "2024-01-01"
  • "2024-01-05"
  • "2024-05-01"

This happens because they are parsed as dates, except for the one with the 'Foo' suffix.

Incorrect ordering of mixed-alphanumeric strings with leading 0s

var naturalOrderby = require("natural-orderby")

naturalOrderby.orderBy(["05", "06", "07*", "08A", "09 B", "10", "11", "12A", "13"])

Expected result: no change. Actual result:

["05", "06", "07*", "10", "11", "12A", "13", "08A", "09 B"]

See https://runkit.com/embed/b88ooo12p3ap

I think I have the specifics pinned down in the title, but I'm not sure if that's quite it. I know repeating the test with numbers ranging from 15 to 23 behaves as expected, and I can't find any non-alphabetic characters that prompt the same error.

Typescript declaration

Do you have any plans to also support Typescript by adding a declaration file?

For now I'm using this, to have it work in Typescript as well:

export function compare(options: any): any;
export function orderBy(collection: any, identifiers: any, orders: any): any;

export namespace compare {
    const prototype: {
    };
}

export namespace orderBy {
    const prototype: {
    };
}

But it is an own inferred declaration, so 'any' types all over.

Incorrect difference in node-natural-sort vs natural-orderBy

With these strings:

const paths = [ 
  'IMG_0001.JPG',
  'IMG_0002.JPG',
  'IMG_0010.JPG',
  'IMG_0011.JPG',
  'IMG_0020.JPG',
  'IMG_0021.JPG' 
]

With node-natural-sort (expected/correct behavior):

import naturalSort from "node-natural-sort";
paths.sort(naturalSort());

//  'IMG_0001.JPG',
//  'IMG_0002.JPG',
//  'IMG_0010.JPG',
//  'IMG_0011.JPG',
//  'IMG_0020.JPG',
//  'IMG_0021.JPG'

With natural-orderby (unexpected/incorrect behavior):

import { orderBy } from "natural-orderby";

orderBy(paths)

//  'IMG_0010.JPG',
//  'IMG_0020.JPG',
//  'IMG_0001.JPG',
//  'IMG_0002.JPG',
//  'IMG_0011.JPG',
//  'IMG_0021.JPG' 

Thanks for the great library!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.