sortBy.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _map = require('./map.js');
  6. var _map2 = _interopRequireDefault(_map);
  7. var _wrapAsync = require('./internal/wrapAsync.js');
  8. var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
  9. var _awaitify = require('./internal/awaitify.js');
  10. var _awaitify2 = _interopRequireDefault(_awaitify);
  11. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  12. /**
  13. * Sorts a list by the results of running each `coll` value through an async
  14. * `iteratee`.
  15. *
  16. * @name sortBy
  17. * @static
  18. * @memberOf module:Collections
  19. * @method
  20. * @category Collection
  21. * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
  22. * @param {AsyncFunction} iteratee - An async function to apply to each item in
  23. * `coll`.
  24. * The iteratee should complete with a value to use as the sort criteria as
  25. * its `result`.
  26. * Invoked with (item, callback).
  27. * @param {Function} callback - A callback which is called after all the
  28. * `iteratee` functions have finished, or an error occurs. Results is the items
  29. * from the original `coll` sorted by the values returned by the `iteratee`
  30. * calls. Invoked with (err, results).
  31. * @returns {Promise} a promise, if no callback passed
  32. * @example
  33. *
  34. * // bigfile.txt is a file that is 251100 bytes in size
  35. * // mediumfile.txt is a file that is 11000 bytes in size
  36. * // smallfile.txt is a file that is 121 bytes in size
  37. *
  38. * // asynchronous function that returns the file size in bytes
  39. * function getFileSizeInBytes(file, callback) {
  40. * fs.stat(file, function(err, stat) {
  41. * if (err) {
  42. * return callback(err);
  43. * }
  44. * callback(null, stat.size);
  45. * });
  46. * }
  47. *
  48. * // Using callbacks
  49. * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes,
  50. * function(err, results) {
  51. * if (err) {
  52. * console.log(err);
  53. * } else {
  54. * console.log(results);
  55. * // results is now the original array of files sorted by
  56. * // file size (ascending by default), e.g.
  57. * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
  58. * }
  59. * }
  60. * );
  61. *
  62. * // By modifying the callback parameter the
  63. * // sorting order can be influenced:
  64. *
  65. * // ascending order
  66. * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) {
  67. * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
  68. * if (getFileSizeErr) return callback(getFileSizeErr);
  69. * callback(null, fileSize);
  70. * });
  71. * }, function(err, results) {
  72. * if (err) {
  73. * console.log(err);
  74. * } else {
  75. * console.log(results);
  76. * // results is now the original array of files sorted by
  77. * // file size (ascending by default), e.g.
  78. * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
  79. * }
  80. * }
  81. * );
  82. *
  83. * // descending order
  84. * async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) {
  85. * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
  86. * if (getFileSizeErr) {
  87. * return callback(getFileSizeErr);
  88. * }
  89. * callback(null, fileSize * -1);
  90. * });
  91. * }, function(err, results) {
  92. * if (err) {
  93. * console.log(err);
  94. * } else {
  95. * console.log(results);
  96. * // results is now the original array of files sorted by
  97. * // file size (ascending by default), e.g.
  98. * // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt']
  99. * }
  100. * }
  101. * );
  102. *
  103. * // Error handling
  104. * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes,
  105. * function(err, results) {
  106. * if (err) {
  107. * console.log(err);
  108. * // [ Error: ENOENT: no such file or directory ]
  109. * } else {
  110. * console.log(results);
  111. * }
  112. * }
  113. * );
  114. *
  115. * // Using Promises
  116. * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes)
  117. * .then( results => {
  118. * console.log(results);
  119. * // results is now the original array of files sorted by
  120. * // file size (ascending by default), e.g.
  121. * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
  122. * }).catch( err => {
  123. * console.log(err);
  124. * });
  125. *
  126. * // Error handling
  127. * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes)
  128. * .then( results => {
  129. * console.log(results);
  130. * }).catch( err => {
  131. * console.log(err);
  132. * // [ Error: ENOENT: no such file or directory ]
  133. * });
  134. *
  135. * // Using async/await
  136. * (async () => {
  137. * try {
  138. * let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
  139. * console.log(results);
  140. * // results is now the original array of files sorted by
  141. * // file size (ascending by default), e.g.
  142. * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
  143. * }
  144. * catch (err) {
  145. * console.log(err);
  146. * }
  147. * })();
  148. *
  149. * // Error handling
  150. * async () => {
  151. * try {
  152. * let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
  153. * console.log(results);
  154. * }
  155. * catch (err) {
  156. * console.log(err);
  157. * // [ Error: ENOENT: no such file or directory ]
  158. * }
  159. * }
  160. *
  161. */
  162. function sortBy(coll, iteratee, callback) {
  163. var _iteratee = (0, _wrapAsync2.default)(iteratee);
  164. return (0, _map2.default)(coll, (x, iterCb) => {
  165. _iteratee(x, (err, criteria) => {
  166. if (err) return iterCb(err);
  167. iterCb(err, { value: x, criteria });
  168. });
  169. }, (err, results) => {
  170. if (err) return callback(err);
  171. callback(null, results.sort(comparator).map(v => v.value));
  172. });
  173. function comparator(left, right) {
  174. var a = left.criteria,
  175. b = right.criteria;
  176. return a < b ? -1 : a > b ? 1 : 0;
  177. }
  178. }
  179. exports.default = (0, _awaitify2.default)(sortBy, 3);
  180. module.exports = exports['default'];