-
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
Conversation
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.
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.
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.
lib/groupByLimit.js
Outdated
export default doParallelLimit(function(eachFn, coll, iteratee, callback) { | ||
callback = callback || noop; | ||
coll = coll || []; | ||
var result = {}; |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
mocha_test/groupBy.js
Outdated
}); | ||
}); | ||
|
||
it('with reflect', function(done) { |
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 don't think the reflect
tests are useful here.
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.
Good point, I'll remove them, thanks!
lib/groupBy.js
Outdated
* 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we use context anywhere else?
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.
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.
Choose a reason for hiding this comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
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
groupByLimit
follows the concurrency limit) frommocha_test/map.js
, while including a few specificgroupBy
tests. 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.