sortBy.js

  1. import arrayMap from 'lodash/_arrayMap';
  2. import property from 'lodash/_baseProperty';
  3. import map from './map';
  4. import wrapAsync from './internal/wrapAsync';
  5. /**
  6. * Sorts a list by the results of running each `coll` value through an async
  7. * `iteratee`.
  8. *
  9. * @name sortBy
  10. * @static
  11. * @memberOf module:Collections
  12. * @method
  13. * @category Collection
  14. * @param {Array|Iterable|Object} coll - A collection to iterate over.
  15. * @param {AsyncFunction} iteratee - An async function to apply to each item in
  16. * `coll`.
  17. * The iteratee should complete with a value to use as the sort criteria as
  18. * its `result`.
  19. * Invoked with (item, callback).
  20. * @param {Function} callback - A callback which is called after all the
  21. * `iteratee` functions have finished, or an error occurs. Results is the items
  22. * from the original `coll` sorted by the values returned by the `iteratee`
  23. * calls. Invoked with (err, results).
  24. * @example
  25. *
  26. * async.sortBy(['file1','file2','file3'], function(file, callback) {
  27. * fs.stat(file, function(err, stats) {
  28. * callback(err, stats.mtime);
  29. * });
  30. * }, function(err, results) {
  31. * // results is now the original array of files sorted by
  32. * // modified date
  33. * });
  34. *
  35. * // By modifying the callback parameter the
  36. * // sorting order can be influenced:
  37. *
  38. * // ascending order
  39. * async.sortBy([1,9,3,5], function(x, callback) {
  40. * callback(null, x);
  41. * }, function(err,result) {
  42. * // result callback
  43. * });
  44. *
  45. * // descending order
  46. * async.sortBy([1,9,3,5], function(x, callback) {
  47. * callback(null, x*-1); //<- x*-1 instead of x, turns the order around
  48. * }, function(err,result) {
  49. * // result callback
  50. * });
  51. */
  52. export default function sortBy (coll, iteratee, callback) {
  53. var _iteratee = wrapAsync(iteratee);
  54. map(coll, function (x, callback) {
  55. _iteratee(x, function (err, criteria) {
  56. if (err) return callback(err);
  57. callback(null, {value: x, criteria: criteria});
  58. });
  59. }, function (err, results) {
  60. if (err) return callback(err);
  61. callback(null, arrayMap(results.sort(comparator), property('value')));
  62. });
  63. function comparator(left, right) {
  64. var a = left.criteria, b = right.criteria;
  65. return a < b ? -1 : a > b ? 1 : 0;
  66. }
  67. }