@@ -200,7 +200,8 @@ function baseGetTag(value) {
200200 if ( value == null ) {
201201 return value === undefined ? undefinedTag : nullTag ;
202202 }
203- return ( symToStringTag && symToStringTag in Object ( value ) )
203+ value = Object ( value ) ;
204+ return ( symToStringTag && symToStringTag in value )
204205 ? getRawTag ( value )
205206 : objectToString ( value ) ;
206207}
@@ -639,7 +640,7 @@ var freeProcess = moduleExports$1 && freeGlobal.process;
639640/** Used to access faster Node.js helpers. */
640641var nodeUtil = ( function ( ) {
641642 try {
642- return freeProcess && freeProcess . binding && freeProcess . binding ( 'util' ) ;
643+ return freeProcess && freeProcess . binding ( 'util' ) ;
643644 } catch ( e ) { }
644645} ( ) ) ;
645646
@@ -1028,7 +1029,7 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
10281029 *
10291030 * If `map` is passed an Object, the results will be an Array. The results
10301031 * will roughly be in the order of the original Objects' keys (but this can
1031- * vary across JavaScript engines)
1032+ * vary across JavaScript engines).
10321033 *
10331034 * @name map
10341035 * @static
@@ -1827,17 +1828,15 @@ function asciiToArray(string) {
18271828
18281829/** Used to compose unicode character classes. */
18291830var rsAstralRange = '\\ud800-\\udfff' ;
1830- var rsComboMarksRange = '\\u0300-\\u036f' ;
1831- var reComboHalfMarksRange = '\\ufe20-\\ufe2f' ;
1832- var rsComboSymbolsRange = '\\u20d0-\\u20ff' ;
1833- var rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange ;
1831+ var rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23' ;
1832+ var rsComboSymbolsRange = '\\u20d0-\\u20f0' ;
18341833var rsVarRange = '\\ufe0e\\ufe0f' ;
18351834
18361835/** Used to compose unicode capture groups. */
18371836var rsZWJ = '\\u200d' ;
18381837
18391838/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
1840- var reHasUnicode = RegExp ( '[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']' ) ;
1839+ var reHasUnicode = RegExp ( '[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']' ) ;
18411840
18421841/**
18431842 * Checks if `string` contains Unicode symbols.
@@ -1852,15 +1851,13 @@ function hasUnicode(string) {
18521851
18531852/** Used to compose unicode character classes. */
18541853var rsAstralRange$1 = '\\ud800-\\udfff' ;
1855- var rsComboMarksRange$1 = '\\u0300-\\u036f' ;
1856- var reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f' ;
1857- var rsComboSymbolsRange$1 = '\\u20d0-\\u20ff' ;
1858- var rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1 ;
1854+ var rsComboMarksRange$1 = '\\u0300-\\u036f\\ufe20-\\ufe23' ;
1855+ var rsComboSymbolsRange$1 = '\\u20d0-\\u20f0' ;
18591856var rsVarRange$1 = '\\ufe0e\\ufe0f' ;
18601857
18611858/** Used to compose unicode capture groups. */
18621859var rsAstral = '[' + rsAstralRange$1 + ']' ;
1863- var rsCombo = '[' + rsComboRange $1 + ']' ;
1860+ var rsCombo = '[' + rsComboMarksRange$1 + rsComboSymbolsRange $1 + ']' ;
18641861var rsFitz = '\\ud83c[\\udffb-\\udfff]' ;
18651862var rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')' ;
18661863var rsNonAstral = '[^' + rsAstralRange$1 + ']' ;
@@ -3433,6 +3430,114 @@ function forever(fn, errback) {
34333430 next ( ) ;
34343431}
34353432
3433+ /**
3434+ * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.
3435+ *
3436+ * @name groupByLimit
3437+ * @static
3438+ * @memberOf module:Collections
3439+ * @method
3440+ * @see [async.groupBy]{@link module:Collections.groupBy}
3441+ * @category Collection
3442+ * @param {Array|Iterable|Object } coll - A collection to iterate over.
3443+ * @param {number } limit - The maximum number of async operations at a time.
3444+ * @param {Function } iteratee - A function to apply to each item in `coll`.
3445+ * The iteratee is passed a `callback(err, key)` which must be called once it
3446+ * has completed with an error (which can be `null`) and the `key` to group the
3447+ * value under. Invoked with (value, callback).
3448+ * @param {Function } [callback] - A callback which is called when all `iteratee`
3449+ * functions have finished, or an error occurs. Result is an `Object` whoses
3450+ * properties are arrays of values which returned the corresponding key.
3451+ */
3452+ var groupByLimit = function ( coll , limit , iteratee , callback ) {
3453+ callback = callback || noop ;
3454+
3455+ mapLimit ( coll , limit , function ( val , callback ) {
3456+ iteratee ( val , function ( err , key ) {
3457+ if ( err ) return callback ( err ) ;
3458+ return callback ( null , { key : key , val : val } ) ;
3459+ } ) ;
3460+ } , function ( err , mapResults ) {
3461+ var result = { } ;
3462+ // from MDN, handle object having an `hasOwnProperty` prop
3463+ var hasOwnProperty = Object . prototype . hasOwnProperty ;
3464+
3465+ for ( var i = 0 ; i < mapResults . length ; i ++ ) {
3466+ if ( mapResults [ i ] ) {
3467+ var key = mapResults [ i ] . key ;
3468+ var val = mapResults [ i ] . val ;
3469+
3470+ if ( hasOwnProperty . call ( result , key ) ) {
3471+ result [ key ] . push ( val ) ;
3472+ } else {
3473+ result [ key ] = [ val ] ;
3474+ }
3475+ }
3476+ }
3477+
3478+ return callback ( err , result ) ;
3479+ } ) ;
3480+ } ;
3481+
3482+ /**
3483+ * Returns a new object, where each value corresponds to an array of items, from
3484+ * `coll`, that returned the corresponding key. That is, the keys of the object
3485+ * correspond to the values passed to the `iteratee` callback.
3486+ *
3487+ * Note: Since this function applies the `iteratee` to each item in parallel,
3488+ * there is no guarantee that the `iteratee` functions will complete in order.
3489+ * However, the values for each key in the `result` will be in the same order as
3490+ * the original `coll`. For Objects, the values will roughly be in the order of
3491+ * the original Objects' keys (but this can vary across JavaScript engines).
3492+ *
3493+ * @name groupBy
3494+ * @static
3495+ * @memberOf module:Collections
3496+ * @method
3497+ * @category Collection
3498+ * @param {Array|Iterable|Object } coll - A collection to iterate over.
3499+ * @param {Function } iteratee - A function to apply to each item in `coll`.
3500+ * The iteratee is passed a `callback(err, key)` which must be called once it
3501+ * has completed with an error (which can be `null`) and the `key` to group the
3502+ * value under. Invoked with (value, callback).
3503+ * @param {Function } [callback] - A callback which is called when all `iteratee`
3504+ * functions have finished, or an error occurs. Result is an `Object` whoses
3505+ * properties are arrays of values which returned the corresponding key.
3506+ * @example
3507+ *
3508+ * async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) {
3509+ * db.findById(userId, function(err, user) {
3510+ * if (err) return callback(err);
3511+ * return callback(null, user.age);
3512+ * });
3513+ * }, function(err, result) {
3514+ * // result is object containing the userIds grouped by age
3515+ * // e.g. { 30: ['userId1', 'userId3'], 42: ['userId2']};
3516+ * });
3517+ */
3518+ var groupBy = doLimit ( groupByLimit , Infinity ) ;
3519+
3520+ /**
3521+ * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.
3522+ *
3523+ * @name groupBySeries
3524+ * @static
3525+ * @memberOf module:Collections
3526+ * @method
3527+ * @see [async.groupBy]{@link module:Collections.groupBy}
3528+ * @category Collection
3529+ * @param {Array|Iterable|Object } coll - A collection to iterate over.
3530+ * @param {number } limit - The maximum number of async operations at a time.
3531+ * @param {Function } iteratee - A function to apply to each item in `coll`.
3532+ * The iteratee is passed a `callback(err, key)` which must be called once it
3533+ * has completed with an error (which can be `null`) and the `key` to group the
3534+ * value under. Invoked with (value, callback).
3535+ * @param {Function } [callback] - A callback which is called when all `iteratee`
3536+ * functions have finished, or an error occurs. Result is an `Object` whoses
3537+ * properties are arrays of values which returned the corresponding key.
3538+ */
3539+ var groupBySeries = doLimit ( groupByLimit , 1 ) ;
3540+
34363541/**
34373542 * Logs the result of an `async` function to the `console`. Only works in
34383543 * Node.js or in browsers that support `console.log` and `console.error` (such
@@ -3707,6 +3812,8 @@ function _parallel(eachfn, tasks, callback) {
37073812 * any I/O, they will actually be executed in series. Any synchronous setup
37083813 * sections for each task will happen one after the other. JavaScript remains
37093814 * single-threaded.
3815+ * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the
3816+ * execution of other tasks when a task fails.
37103817 *
37113818 * It is also possible to use an object instead of an array. Each property will
37123819 * be run as a function and the results will be passed to the final `callback`
@@ -4881,7 +4988,7 @@ var timesSeries = doLimit(timeLimit, 1);
48814988 * })
48824989 */
48834990function transform ( coll , accumulator , iteratee , callback ) {
4884- if ( arguments . length == = 3 ) {
4991+ if ( arguments . length < = 3 ) {
48854992 callback = iteratee ;
48864993 iteratee = accumulator ;
48874994 accumulator = isArray ( coll ) ? [ ] : { } ;
@@ -5130,6 +5237,9 @@ var index = {
51305237 filterLimit : filterLimit ,
51315238 filterSeries : filterSeries ,
51325239 forever : forever ,
5240+ groupBy : groupBy ,
5241+ groupByLimit : groupByLimit ,
5242+ groupBySeries : groupBySeries ,
51335243 log : log ,
51345244 map : map ,
51355245 mapLimit : mapLimit ,
@@ -5222,6 +5332,9 @@ exports.filter = filter;
52225332exports . filterLimit = filterLimit ;
52235333exports . filterSeries = filterSeries ;
52245334exports . forever = forever ;
5335+ exports . groupBy = groupBy ;
5336+ exports . groupByLimit = groupByLimit ;
5337+ exports . groupBySeries = groupBySeries ;
52255338exports . log = log ;
52265339exports . map = map ;
52275340exports . mapLimit = mapLimit ;
0 commit comments