[#1348] initial groupBy implementation#1364
Conversation
aearly
left a comment
There was a problem hiding this comment.
Overall, LGTM. The implementation is pretty simple. 👍
| * @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 |
There was a problem hiding this comment.
I think this is a decent example.
| export default doParallelLimit(function(eachFn, coll, iteratee, callback) { | ||
| callback = callback || noop; | ||
| coll = coll || []; | ||
| var result = {}; |
There was a problem hiding this comment.
What do you think about having result = Object.create(null)? Then instead of hasOwnProperty.call(...) down below, you could just do key in result.
There was a problem hiding this comment.
I prefer to avoid using Object.create(null) as the behaviour can not be emulated consistently in older environments. I prefer using standard objects + hasOwn (hasOwn tends to be faster anyway last time I checked)
There was a problem hiding this comment.
I wouldn't mind using Object.create(null) internally, but I'd also prefer to avoid using it for objects returned to the user. The user might use something like result.hasOwnProperty(anImportantKey) somewhere later in the code, which would result in a TypeError.
There was a problem hiding this comment.
Object.create(null) is ES5, which is our minimum required version as of 2.0. @hargasinski brings up a good point though, best not to use it because of that.
| }); | ||
| }); | ||
|
|
||
| it('with reflect', function(done) { |
There was a problem hiding this comment.
I don't think the reflect tests are useful here.
There was a problem hiding this comment.
Good point, I'll remove them, thanks!
| * 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 and there is | ||
| * no guarantee that grouped items will appear in the same order as in `coll`. |
There was a problem hiding this comment.
Reconsidering about groupBy again I question whether its better implemented synchronously after all the asynchronous work has been resolved, as making the order fixed in an asynchronous processing flow would make things much more complicated
There was a problem hiding this comment.
Just to make sure I understand, do you mean kinda like ./internal/filter.js where it asynchronously transforms the values, but synchronously filters them afterwards? I could look into that tomorrow.
| }, val * 25); | ||
| } | ||
|
|
||
| context('groupBy', function() { |
There was a problem hiding this comment.
Do we use context anywhere else?
There was a problem hiding this comment.
Yes, I was looking at the mapValues tests when I added that. We use it in the compose and queue tests too.
It's more personal preference than anything, but I feel like it makes the test results easier to read and it forces them to be more organized:

| var hasOwnProperty = Object.prototype.hasOwnProperty; | ||
|
|
||
| for (var i = 0; i < mapResults.length; i++) { | ||
| if (mapResults[i]) { |
There was a problem hiding this comment.
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.
I like the continue style, but that's just like... ...my opinion, man.
|
BTW, the CI failures for this were bogus, so I'd say this is 👍 to merge. |
|
I wanted to make sure @megawac is good with the implementation before merging. |
|
Yep, there's a couple other enhancements ready too. |
|
@hargasinski I'll let you do the honors, otherwise I'll do it later this evening. |
|
@aearly thank you, but I don't have permission to publish |
|
Ok, published! Thanks for writing the changelog. |
|
Just to know, there is no documentation for this? or was not generated 🤔 |
|
There was an error publishing docs. Are we using the gh-pages branch, or the docs/ folder now? Either way, |
|
I just updated the Edit: we're still using the |
|
@aearly rerunning I couldn't figure out what was causing the exact issue (it might have been a bug in an older version of For now, if updating |
|
Thanks for looking in to this. It appears there was an incompatibility with Node 6.3 streams that was making it fail: mafintosh/duplexify@acf662f (I think I last published with Node 6.2) Updating it fixes things. I say we keep with |
My attempt at implementing groupBy for #1348 (and I guess #214). This is my first feature implementation for
async, so feedback is greatly appreciated.I may have been a little excessive with the testing, as I ported a lot of the generic tests (like ensuring
groupByLimitfollows the concurrency limit) frommocha_test/map.js, while including a few specificgroupBytests. Also, the example I used for the docs isn't that great as I couldn't really come up with anything concise but illustrative. I'd like to change it before merging, if anyone has any ideas.