($parse)
| 20902 | orderByFilter.$inject = ['$parse']; |
| 20903 | |
| 20904 | function orderByFilter($parse) { |
| 20905 | return function (array, sortPredicate, reverseOrder) { |
| 20906 | if (array == null) return array; |
| 20907 | if (!isArrayLike(array)) { |
| 20908 | throw minErr('orderBy')('notarray', 'Expected array but received: {0}', array); |
| 20909 | } |
| 20910 | |
| 20911 | if (!isArray(sortPredicate)) { |
| 20912 | sortPredicate = [sortPredicate]; |
| 20913 | } |
| 20914 | if (sortPredicate.length === 0) { |
| 20915 | sortPredicate = ['+']; |
| 20916 | } |
| 20917 | |
| 20918 | var predicates = processPredicates(sortPredicate, reverseOrder); |
| 20919 | // Add a predicate at the end that evaluates to the element index. This makes the |
| 20920 | // sort stable as it works as a tie-breaker when all the input predicates cannot |
| 20921 | // distinguish between two elements. |
| 20922 | predicates.push({ get: function () { return {}; }, descending: reverseOrder ? -1 : 1 }); |
| 20923 | |
| 20924 | // The next three lines are a version of a Swartzian Transform idiom from Perl |
| 20925 | // (sometimes called the Decorate-Sort-Undecorate idiom) |
| 20926 | // See https://en.wikipedia.org/wiki/Schwartzian_transform |
| 20927 | var compareValues = Array.prototype.map.call(array, getComparisonObject); |
| 20928 | compareValues.sort(doComparison); |
| 20929 | array = compareValues.map(function (item) { return item.value; }); |
| 20930 | |
| 20931 | return array; |
| 20932 | |
| 20933 | function getComparisonObject(value, index) { |
| 20934 | return { |
| 20935 | value: value, |
| 20936 | predicateValues: predicates.map(function (predicate) { |
| 20937 | return getPredicateValue(predicate.get(value), index); |
| 20938 | }) |
| 20939 | }; |
| 20940 | } |
| 20941 | |
| 20942 | function doComparison(v1, v2) { |
| 20943 | var result = 0; |
| 20944 | for (var index = 0, length = predicates.length; index < length; ++index) { |
| 20945 | result = compare(v1.predicateValues[index], v2.predicateValues[index]) * |
| 20946 | predicates[index].descending; |
| 20947 | if (result) break; |
| 20948 | } |
| 20949 | return result; |
| 20950 | } |
| 20951 | }; |
| 20952 | |
| 20953 | function processPredicates(sortPredicate, reverseOrder) { |
| 20954 | reverseOrder = reverseOrder ? -1 : 1; |
| 20955 | return sortPredicate.map(function (predicate) { |
| 20956 | var descending = 1, get = identity; |
| 20957 | |
| 20958 | if (isFunction(predicate)) { |
| 20959 | get = predicate; |
| 20960 | } else if (isString(predicate)) { |
| 20961 | if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) { |
nothing calls this directly
no test coverage detected