-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#1348] initial groupBy implementation #1364
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import doLimit from './internal/doLimit'; | ||
import groupByLimit from './groupByLimit'; | ||
|
||
/** | ||
* Returns a new object, where each value corresponds to an array of items, from | ||
* `coll`, that returned the corresponding key. That is, the keys of the object | ||
* correspond to the values passed to the `iteratee` callback. | ||
* | ||
* Note: Since this function applies the `iteratee` to each item in parallel, | ||
* there is no guarantee that the `iteratee` functions will complete in order. | ||
* However, the values for each key in the `result` will be in the same order as | ||
* the original `coll`. For Objects, the values will roughly be in the order of | ||
* the original Objects' keys (but this can vary across JavaScript engines). | ||
* | ||
* @name groupBy | ||
* @static | ||
* @memberOf module:Collections | ||
* @method | ||
* @category Collection | ||
* @param {Array|Iterable|Object} coll - A collection to iterate over. | ||
* @param {Function} iteratee - A function to apply to each item in `coll`. | ||
* The iteratee is passed a `callback(err, key)` which must be called once it | ||
* has completed with an error (which can be `null`) and the `key` to group the | ||
* value under. Invoked with (value, callback). | ||
* @param {Function} [callback] - A callback which is called when all `iteratee` | ||
* functions have finished, or an error occurs. Result is an `Object` whoses | ||
* properties are arrays of values which returned the corresponding key. | ||
* @example | ||
* | ||
* async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) { | ||
* db.findById(userId, function(err, user) { | ||
* if (err) return callback(err); | ||
* return callback(null, user.age); | ||
* }); | ||
* }, function(err, result) { | ||
* // result is object containing the userIds grouped by age | ||
* // e.g. { 30: ['userId1', 'userId3'], 42: ['userId2']}; | ||
* }); | ||
*/ | ||
export default doLimit(groupByLimit, Infinity); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import noop from 'lodash/noop'; | ||
import mapLimit from './mapLimit'; | ||
|
||
/** | ||
* The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time. | ||
* | ||
* @name groupByLimit | ||
* @static | ||
* @memberOf module:Collections | ||
* @method | ||
* @see [async.groupBy]{@link module:Collections.groupBy} | ||
* @category Collection | ||
* @param {Array|Iterable|Object} coll - A collection to iterate over. | ||
* @param {number} limit - The maximum number of async operations at a time. | ||
* @param {Function} iteratee - A function to apply to each item in `coll`. | ||
* The iteratee is passed a `callback(err, key)` which must be called once it | ||
* has completed with an error (which can be `null`) and the `key` to group the | ||
* value under. Invoked with (value, callback). | ||
* @param {Function} [callback] - A callback which is called when all `iteratee` | ||
* functions have finished, or an error occurs. Result is an `Object` whoses | ||
* properties are arrays of values which returned the corresponding key. | ||
*/ | ||
export default function(coll, limit, iteratee, callback) { | ||
callback = callback || noop; | ||
|
||
mapLimit(coll, limit, function(val, callback) { | ||
iteratee(val, function(err, key) { | ||
if (err) return callback(err); | ||
return callback(null, {key: key, val: val}); | ||
}); | ||
}, function(err, mapResults) { | ||
var result = {}; | ||
// from MDN, handle object having an `hasOwnProperty` prop | ||
var hasOwnProperty = Object.prototype.hasOwnProperty; | ||
|
||
for (var i = 0; i < mapResults.length; i++) { | ||
if (mapResults[i]) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Code style question: is there a preference for: if (!mapResults[i]) continue;
// do something ... versus if (mapResults[i]) {
// do something ...
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the |
||
var key = mapResults[i].key; | ||
var val = mapResults[i].val; | ||
|
||
if (hasOwnProperty.call(result, key)) { | ||
result[key].push(val); | ||
} else { | ||
result[key] = [val]; | ||
} | ||
} | ||
} | ||
|
||
return callback(err, result); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import doLimit from './internal/doLimit'; | ||
import groupByLimit from './groupByLimit'; | ||
|
||
/** | ||
* The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time. | ||
* | ||
* @name groupBySeries | ||
* @static | ||
* @memberOf module:Collections | ||
* @method | ||
* @see [async.groupBy]{@link module:Collections.groupBy} | ||
* @category Collection | ||
* @param {Array|Iterable|Object} coll - A collection to iterate over. | ||
* @param {number} limit - The maximum number of async operations at a time. | ||
* @param {Function} iteratee - A function to apply to each item in `coll`. | ||
* The iteratee is passed a `callback(err, key)` which must be called once it | ||
* has completed with an error (which can be `null`) and the `key` to group the | ||
* value under. Invoked with (value, callback). | ||
* @param {Function} [callback] - A callback which is called when all `iteratee` | ||
* functions have finished, or an error occurs. Result is an `Object` whoses | ||
* properties are arrays of values which returned the corresponding key. | ||
*/ | ||
export default doLimit(groupByLimit, 1); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a decent example.