($parse)
| 19390 | */ |
| 19391 | orderByFilter.$inject = ['$parse']; |
| 19392 | function orderByFilter($parse) { |
| 19393 | return function(array, sortPredicate, reverseOrder) { |
| 19394 | |
| 19395 | if (!(isArrayLike(array))) return array; |
| 19396 | |
| 19397 | if (!isArray(sortPredicate)) { sortPredicate = [sortPredicate]; } |
| 19398 | if (sortPredicate.length === 0) { sortPredicate = ['+']; } |
| 19399 | |
| 19400 | var predicates = processPredicates(sortPredicate, reverseOrder); |
| 19401 | // Add a predicate at the end that evaluates to the element index. This makes the |
| 19402 | // sort stable as it works as a tie-breaker when all the input predicates cannot |
| 19403 | // distinguish between two elements. |
| 19404 | predicates.push({ get: function() { return {}; }, descending: reverseOrder ? -1 : 1}); |
| 19405 | |
| 19406 | // The next three lines are a version of a Swartzian Transform idiom from Perl |
| 19407 | // (sometimes called the Decorate-Sort-Undecorate idiom) |
| 19408 | // See https://en.wikipedia.org/wiki/Schwartzian_transform |
| 19409 | var compareValues = Array.prototype.map.call(array, getComparisonObject); |
| 19410 | compareValues.sort(doComparison); |
| 19411 | array = compareValues.map(function(item) { return item.value; }); |
| 19412 | |
| 19413 | return array; |
| 19414 | |
| 19415 | function getComparisonObject(value, index) { |
| 19416 | return { |
| 19417 | value: value, |
| 19418 | predicateValues: predicates.map(function(predicate) { |
| 19419 | return getPredicateValue(predicate.get(value), index); |
| 19420 | }) |
| 19421 | }; |
| 19422 | } |
| 19423 | |
| 19424 | function doComparison(v1, v2) { |
| 19425 | var result = 0; |
| 19426 | for (var index=0, length = predicates.length; index < length; ++index) { |
| 19427 | result = compare(v1.predicateValues[index], v2.predicateValues[index]) * predicates[index].descending; |
| 19428 | if (result) break; |
| 19429 | } |
| 19430 | return result; |
| 19431 | } |
| 19432 | }; |
| 19433 | |
| 19434 | function processPredicates(sortPredicate, reverseOrder) { |
| 19435 | reverseOrder = reverseOrder ? -1 : 1; |
| 19436 | return sortPredicate.map(function(predicate) { |
| 19437 | var descending = 1, get = identity; |
| 19438 | |
| 19439 | if (isFunction(predicate)) { |
| 19440 | get = predicate; |
| 19441 | } else if (isString(predicate)) { |
| 19442 | if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) { |
| 19443 | descending = predicate.charAt(0) == '-' ? -1 : 1; |
| 19444 | predicate = predicate.substring(1); |
| 19445 | } |
| 19446 | if (predicate !== '') { |
| 19447 | get = $parse(predicate); |
| 19448 | if (get.constant) { |
| 19449 | var key = get(); |
nothing calls this directly
no test coverage detected