|
40 | 40 | * index: ...
|
41 | 41 | * }
|
42 | 42 | * ```
|
| 43 | + * **Note:** `null` values use `'null'` as their type. |
43 | 44 | * 2. The comparator function is used to sort the items, based on the derived values, types and
|
44 | 45 | * indices.
|
45 | 46 | *
|
|
74 | 75 | *
|
75 | 76 | * The default, built-in comparator should be sufficient for most usecases. In short, it compares
|
76 | 77 | * numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to
|
77 |
| - * using their index in the original collection, and sorts values of different types by type. |
| 78 | + * using their index in the original collection, sorts values of different types by type and puts |
| 79 | + * `undefined` and `null` values at the end of the sorted list. |
78 | 80 | *
|
79 | 81 | * More specifically, it follows these steps to determine the relative order of items:
|
80 | 82 | *
|
81 |
| - * 1. If the compared values are of different types, compare the types themselves alphabetically. |
| 83 | + * 1. If the compared values are of different types: |
| 84 | + * - If one of the values is undefined, consider it "greater than" the other. |
| 85 | + * - Else if one of the values is null, consider it "greater than" the other. |
| 86 | + * - Else compare the types themselves alphabetically. |
82 | 87 | * 2. If both values are of type `string`, compare them alphabetically in a case- and
|
83 | 88 | * locale-insensitive way.
|
84 | 89 | * 3. If both values are objects, compare their indices instead.
|
|
89 | 94 | *
|
90 | 95 | * **Note:** If you notice numbers not being sorted as expected, make sure they are actually being
|
91 | 96 | * saved as numbers and not strings.
|
92 |
| - * **Note:** For the purpose of sorting, `null` values are treated as the string `'null'` (i.e. |
93 |
| - * `type: 'string'`, `value: 'null'`). This may cause unexpected sort order relative to |
94 |
| - * other values. |
| 97 | + * **Note:** For the purpose of sorting, `null` and `undefined` are considered "greater than" |
| 98 | + * any other value (with undefined "greater than" null). This effectively means that `null` |
| 99 | + * and `undefined` values end up at the end of a list sorted in ascending order. |
| 100 | + * **Note:** `null` values use `'null'` as their type to be able to distinguish them from objects. |
95 | 101 | *
|
96 | 102 | * @param {Array|ArrayLike} collection - The collection (array or array-like object) to sort.
|
97 | 103 | * @param {(Function|string|Array.<Function|string>)=} expression - A predicate (or list of
|
@@ -658,8 +664,7 @@ function orderByFilter($parse) {
|
658 | 664 | function getPredicateValue(value, index) {
|
659 | 665 | var type = typeof value;
|
660 | 666 | if (value === null) {
|
661 |
| - type = 'string'; |
662 |
| - value = 'null'; |
| 667 | + type = 'null'; |
663 | 668 | } else if (type === 'object') {
|
664 | 669 | value = objectValue(value);
|
665 | 670 | }
|
@@ -690,7 +695,11 @@ function orderByFilter($parse) {
|
690 | 695 | result = value1 < value2 ? -1 : 1;
|
691 | 696 | }
|
692 | 697 | } else {
|
693 |
| - result = type1 < type2 ? -1 : 1; |
| 698 | + result = (type1 === 'undefined') ? 1 : |
| 699 | + (type2 === 'undefined') ? -1 : |
| 700 | + (type1 === 'null') ? 1 : |
| 701 | + (type2 === 'null') ? -1 : |
| 702 | + (type1 < type2) ? -1 : 1; |
694 | 703 | }
|
695 | 704 |
|
696 | 705 | return result;
|
|
0 commit comments