Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ascendNatural and descendNatural functions #3442

Merged
merged 6 commits into from May 14, 2024

Conversation

sebbayer
Copy link
Contributor

@sebbayer sebbayer commented Feb 29, 2024

There is no built-in way to do natural sorting on strings, therefore I propose ascendNatural and descendNatural to add this functionality via localeCompare. Use exactly like you would with ascend and descend. The implementation is also very similar.

const x = [ '3', '10', 'z', '1', 'a' ]

sort(ascend(identity), x)
> ["1", "10", "3", "a", "z"]

sort(ascendNatural(identity), x)
> ["1", "3", "10", "a", "z"]

Copy link

Coverage
> ramda@0.29.1 coverage:summary
> BABEL_ENV=cjs nyc --reporter=text-summary mocha -- --reporter=min --require @babel/register

�[2J�[1;3H
1188 passing (907ms)


=============================== Coverage summary ===============================
Statements   : 94.03% ( 2474/2631 )
Branches     : 85.73% ( 967/1128 )
Functions    : 93.24% ( 552/592 )
Lines        : 94.31% ( 2320/2460 )
================================================================================

Copy link

Coverage
> ramda@0.29.1 coverage:summary
> BABEL_ENV=cjs nyc --reporter=text-summary mocha -- --reporter=min --require @babel/register

�[2J�[1;3H
1188 passing (902ms)


=============================== Coverage summary ===============================
Statements   : 94.03% ( 2474/2631 )
Branches     : 85.73% ( 967/1128 )
Functions    : 93.24% ( 552/592 )
Lines        : 94.31% ( 2320/2460 )
================================================================================

@CrossEye
Copy link
Member

CrossEye commented Mar 1, 2024

This seems a useful and well-written PR. These sound like useful additions.

Do others have objections?

@kedashoe
Copy link
Contributor

kedashoe commented Mar 1, 2024

Feels a bit niche to me? Considering we can write R.sortWith([(a, b) => a.localeCompare(b)], xs). Also the implementation takes away our ability to call localeCompare with our own arguments.. why are we setting { numeric: true } for the options?

@sebbayer
Copy link
Contributor Author

sebbayer commented Mar 1, 2024

Thanks for the feedback. Before implementing I was looking up what natural sort order is supposed to do, and by definition in Wikipedia it is

the ordering of strings in alphabetical order, except that multi-digit numbers are treated atomically, i.e., as if they were a single character

So for the most intuitive usage (I thought) I had set { numeric: true } with no locales option set. If users needed different options, there would be sortWith as mentioned. But "alphabetical order" has a different meaning based on language. So for more flexibility, should we be able to pass the locales and options parameters of localeCompare?

@semmel
Copy link
Contributor

semmel commented Apr 27, 2024

Just to revive this proposal, I'd like to add my opinion here too.

Admittedly it's "a bit niche", it fixes sorting text with Ramda. Which is great because <, > comparisons — as ascend and descent perform — do not make sense with text.

If localCompare had been around longer, from the beginning ascend and descent could have used String.localCompare when given String items.

Instead of introducing those two new comparator functions, can you imagine, to change the implementation of ascend and descent for String?

However, the problem is the customization. To sort according to the browser or Node.js locale (language) might be not target-oriented in most cases. I'd suggest to allow to pass at least the language to localCompare.

So that in this case

const
  collectionItemComparator = ascendNatural(identity);
sort(collectionItemComparator('de'), x)

Or should the language come as first argument instead? I.e. is it the least changing argument? sort(ascendNatural('de', identity), x)?

@kedashoe
Copy link
Contributor

Admittedly it's "a bit niche", it fixes sorting text with Ramda. Which is great because <, > comparisons — as ascend and descent perform — do not make sense with text.

Ya and niche was not the right word, ramda could have a better story for sorting by string.

I like language first.

Should this be called localeAscend and localeDescend? Something that immediately implies we are targeting strings here feels appropriate.

@sebbayer sorry for the slow review! Could you add @see references to these new functions from ascend and descend?

Copy link

github-actions bot commented May 7, 2024

Coverage Summary
> ramda@0.30.0 coverage:summary
> BABEL_ENV=cjs nyc --reporter=text-summary mocha -- --reporter=min --require @babel/register

�[2J�[1;3H
1190 passing (1s)


=============================== Coverage summary ===============================
Statements   : 94.04% ( 2477/2634 )
Branches     : 85.73% ( 967/1128 )
Functions    : 93.25% ( 553/593 )
Lines        : 94.32% ( 2323/2463 )
================================================================================

@sebbayer
Copy link
Contributor Author

sebbayer commented May 7, 2024

Sorry for the late reply, I am glad there is still interest in the topic.

@semmel I added the language parameter first as you suggested. I hope I got the function signature right.
@kedashoe references in ascend and descend to the new functions have been added.

I updated the functions with better examples and tests have also been updated.

To my surprise the locale based sorting result was pretty much the same in English, German and French, but for example Swedish has differences. My use case so far was only numeric string sorting. I left the { numeric: true } in the code because I think that is how you would expect it to work.

I still like the ascend and descend prefix to the function names. If you look at the list of functions in the documentation, they would come right after the non-natural sorting functions in the list.

@kedashoe kedashoe merged commit c766083 into ramda:master May 14, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants