-
Notifications
You must be signed in to change notification settings - Fork 27.4k
feat(orderBy): Add null
and undefined
at the end of the sorted list
#16376
Conversation
It looks like travis is failing coz of another commit message:
But it looks like this is a very old commit. I'm somewhat confused 😕 |
Did you fork this branch a while back, possibly in July? Because the commit that is throwing the error was merged back in July this year. Although the commit message checker should only check commits that belong to the PR. |
@Narretz I did fork it awhile back idd. Would rebasing solve it (I doubt) ? |
Rebasing should solve it (it is a bug if it doesn't). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much needed change 👍
A couple of minor coments and should be good to go 🎉
src/ng/filter/orderBy.js
Outdated
@@ -74,11 +75,13 @@ | |||
* | |||
* The default, built-in comparator should be sufficient for most usecases. In short, it compares | |||
* numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to | |||
* using their index in the original collection, and sorts values of different types by type. | |||
* using their index in the original collection, sorts values of different types by type and puts `undefined` and `null` values at the end of the sorted list. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrap lines at 100 chars (everywhere) 🙏
test/ng/filter/orderBySpec.js
Outdated
@@ -309,6 +309,14 @@ describe('Filter: orderBy', function() { | |||
|
|||
expect(orderBy(items, expr)).toEqual(sorted); | |||
}); | |||
|
|||
it('should treat `null` values bigger then all other values except `undefined`', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change to something like:
should consider
null
andundefined
greater than any other value
src/ng/filter/orderBy.js
Outdated
* **Note:** For the purpose of sorting, `null` values are treated as the string `'null'` (i.e. | ||
* `type: 'string'`, `value: 'null'`). This may cause unexpected sort order relative to | ||
* other values. | ||
* **Note:** `null` and `undefined` values are always treated bigger than any other value, where `undefined` is treated bigger than `null`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would change it to something like:
For the purpose of sorting,
null
andundefined
are considered "greater than" any other value (withundefined
"greater than"null
). This effectively means thatnull
andundefined
values end up at the end of a list sorted in ascending order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also add another note about null
values using 'null'
as their type (to more easily distinguish them from objects).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's fine. I would just add another note here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/ng/filter/orderBy.js
Outdated
* 1. If the compared values are of different types, compare the types themselves alphabetically. | ||
* 1. If the compared values are of different types: | ||
* - Explicitly check for `null` and `undefined` values and treat them bigger as any other value. | ||
* - If both values are different from `null` and `undefined`, compare the types themselves alphabetically. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would change the bullets to make the relative order of null
vs undefined
more explicit:
- If one of the values is
undefined
, consider it "greater than" the other.- Else if one of the values is
null
, consider it "greater than" the other.- Else compare the types themselves aplhabetically.
test/ng/filter/orderBySpec.js
Outdated
var expr = null; | ||
var sorted = [false, 999, {}, 'z', null, undefined]; | ||
|
||
expect(orderBy(items, expr)).toEqual(sorted); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be sure, could you also add an expectation for sorting in descending order?
BTW, we need a |
@gkalpak I'll add the BC notice in the commit message and squash the other commits. |
I've added the BC notice, unsure if it's enough or needs an example. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting there 😉
src/ng/filter/orderBy.js
Outdated
* other values. | ||
* **Note:** For the purpose of sorting, null and undefined are considered "greater than" | ||
* any other value (with undefined "greater than" null). This effectively means that null | ||
* and undefined values end up at the end of a list sorted in ascending order. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indent subsequent lines as above.
src/ng/filter/orderBy.js
Outdated
* **Note:** For the purpose of sorting, `null` values are treated as the string `'null'` (i.e. | ||
* `type: 'string'`, `value: 'null'`). This may cause unexpected sort order relative to | ||
* other values. | ||
* **Note:** For the purpose of sorting, null and undefined are considered "greater than" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrap "null" and "undefined" in backticks (as in other places).
src/ng/filter/orderBy.js
Outdated
@@ -690,7 +695,7 @@ function orderByFilter($parse) { | |||
result = value1 < value2 ? -1 : 1; | |||
} | |||
} else { | |||
result = type1 < type2 ? -1 : 1; | |||
result = (type1 === 'undefined') ? 1 : (type2 === 'undefined') ? -1 : (type1 === 'null') ? 1 : (type2 === 'null') ? -1 : (type1 < type2) ? -1 : 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is still >100 chars long 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about using the following instead of wrapping it at 100 :
result = (type1 === 'undefined') ? 1 :
(type2 === 'undefined') ? -1 :
(type1 === 'null') ? 1 :
(type2 === 'null') ? -1 :
(type1 < type2) ? -1 : 1;
I think it improves readability ...
Previously, `null` values where sorted using type `string` resulting in a string comparison. `undefined` values where compared to other values by type and were usually considered greater than other values (since their type happens to start with a `u`), but this was coincidental. This commit ensures that `null` and `undefined ` values are explicitly considered greater than other values (with `undefined` > `null`) and will effectively be put at the end of the sorted list (for ascending order sorting). Closes #15294 BREAKING CHANGE: When using `orderBy` to sort arrays containing `null` values, the `null` values will be considered "greater than" all other values, except for `undefined`. Previously, they were sorted as strings. This will result in different (but more intuitive) sorting order. Before: ```js orderByFilter(['a', undefined, 'o', null, 'z']); //--> 'a', null, 'o', 'z', undefined ``` After: ```js orderByFilter(['a', undefined, 'o', null, 'z']); //--> 'a', 'o', 'z', null, undefined ```
@gkalpak If you're happy with this, I will merge it |
What is the current behavior? (You can also link to an open issue here)
null
values are sorted using typestring
resulting in a string comparison.What is the new behavior (if this is a feature change)?
null
andundefined
values are, explicitly, being put at the end of the sorted list.`Does this PR introduce a breaking change?
Yes
Please check if the PR fulfills these requirements
Other information:
This fixes: #15294