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

orderBy not working with null values #69

Open
jordanbrowneb opened this issue Oct 16, 2019 · 7 comments
Open

orderBy not working with null values #69

jordanbrowneb opened this issue Oct 16, 2019 · 7 comments

Comments

@jordanbrowneb
Copy link

We're getting some really weird behavior when using orderBy on arrays with null in them.

Below is a test case running linq 3.2.1 on node 10.15.3.

const Enumerable = require('linq');

const data = ['2019-10-01', null, '2019-09-12', '2019-09-15', null];
const result = Enumerable.from(data).orderBy(x => x).toArray();

result.forEach(x => console.log(x));

Expected output:

null
null
2019-09-12
2019-09-15
2019-10-01

Actual output:

2019-10-01
null
2019-09-12
2019-09-15
null

Thanks in advance for any help you can provide.

@mihaifm
Copy link
Owner

mihaifm commented Oct 17, 2019

This is the function used for comparison:

compare: function (a, b) {
            return (a === b) ? 0
                 : (a > b) ? 1
                 : -1;
        }

Values are reversed if (a>b).
Unfortunately comparing something with null always returns false.

console.log('2019-09-12' > null)
false

console.log('2019-09-12' < null)
false

One solution would be to pass a better lambda to orderBy, causing the value to be sanitized before comparing:

const result = Enumerable.from(data).orderBy(x => (x===null) ? "" : x).toArray();

@jordanbrowneb
Copy link
Author

Thank you for your quick reply. Do you intend to change the library to better handle nulls like in this case? Or is the workaround you posted going to be the permanent solution?

@mihaifm
Copy link
Owner

mihaifm commented Oct 22, 2019

Not sure yet...
array.sort() does indeed sort the above values but it does so by converting nulls to strings.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

We can probably do the same for this library using some typeof wizzardry, but it feels like a very specific scenario.

@jordanbrowneb
Copy link
Author

Gotcha. It's a fairly common use case for us ( e.g. calling .select(...) to grab a nullable property then sorting it using .orderBy(...) ).

We were surprised that the order returned was not the same as when doing the equivalent calls in C# LINQ. C# will return the expected output I listed earlier.

@zhongchengyi
Copy link
Contributor

This is the function used for comparison:

compare: function (a, b) {
            return (a === b) ? 0
                 : (a > b) ? 1
                 : -1;
        }

Values are reversed if (a>b).
Unfortunately comparing something with null always returns false.

console.log('2019-09-12' > null)
false

console.log('2019-09-12' < null)
false

One solution would be to pass a better lambda to orderBy, causing the value to be sanitized before comparing:

const result = Enumerable.from(data).orderBy(x => (x===null) ? "" : x).toArray();

I suddenly realized that Intl could solve this problem
image

@zhongchengyi
Copy link
Contributor

zhongchengyi commented Mar 12, 2020

Now , you can set compare function , at 3.2.2
Issue: #74

const a= ['2019-10-01', null, '2019-09-12', '2019-09-15', null];
var cf = new Intl.Collator();
Enumerable.from(a).orderBy(x=>x, cf.compare).toArray()

output:
["2019-09-12", "2019-09-15", "2019-10-01", null, null]

You can prepare a custorm compare function to let null in front.

@zhongchengyi
Copy link
Contributor

zhongchengyi commented Mar 12, 2020

warning:

You should have a reasonable initialization parameter,otherwise the result may not be what you want.
see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator

Example:

var cf = new Intl.Collator();
cf.compare(1,2)
//=-1
cf.compare(15,2)
//=-1  (Expected = 1)

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

No branches or pull requests

3 participants