-
Notifications
You must be signed in to change notification settings - Fork 576
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
Proposal: std/collections - first part #993
Conversation
962800c
to
b0f1047
Compare
59f704e
to
41c9a47
Compare
Adds test cases for the `union function. Also applied formatting on the directory, also refactored existing test cases to use the same convention on naming tests etc. Adds the copyright headers to all files in the module.
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.
This looks like a good set of APIs to start with.
I started implementing |
I like the varargs for union and intersect. I am back from vacation now and will continue implementing :-) |
* const numbers = [ 3, 2, 5, 2, 5 ] | ||
* const distinctNumbers = distinct(numbers) | ||
* | ||
* console.assert(distinctNumbers === [ 3, 2, 5 ]) |
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.
nitpick: console.assert
will always fail because their identities are different. assert.deepStrictEqual(distinctNumbers, [3,2,5])
in nodejs or expect(distinctNumbers).toEqual([3,2,5])
in jest might be a better choice.
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.
You are absolutely right - we should make sure that those examples actually work. I just totally missed that. I will put it on my to do list to do a sweep of that in the end.
I am finished with implementations and tests for now - obviously pending review. Will move on to refining types and docs now. |
Amazing work! I was wondering if there’d be a lot of opposition to sticking to intransitive verbs for the functions. I am confused by chunked and permutations — why isn’t it chunk and permute? Then there’s union which definitely is more common… although it could be named concat, or concatUnique since it seems to remove duplicates… but I don’t have a strong opinion about that last one. |
To be honest, names are mostly stolen from |
Amazing work 👍, |
As I understand it, the std lib tries to battle the dependency madness of needing third party code for everything, which is why we decided to do it this way. There has been a lot of discussion around this module on Discord and in the linked Discussions (following the links in the initial post of this PR). |
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 have some comments, most of them are minor nitpick, and obviously there needs to be some more docs. Also make sure that the block comments are formatted to stick within 80 characters and fix the linting errors.
Other than that, great work, looking forward to landing this!
}); | ||
|
||
Deno.test({ | ||
name: "[collections/distinctBy] gets head on noop selector", |
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.
This one feels a bit weird to me; If there are no conditions on which to identify distinct item, how do we determine that they are all equivalent? Shouldn't this return a copy of the initial array instead?
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.
As () => {}
is equivalent to it => undefined
here, it would feel like unexpected magic behavior to me if it would explicitly ignore equality (distinctity? is that a word?) for undefined
. What about null
? ""
? What if undefined
is a legit value in my model?
I wrote those tests before implementing the function, so to mee it seemed like the intuitive behavior to just distinct all values by their produced value - no matter what it is.
export function distinct<T>(array: Array<T>): Array<T> { | ||
const set = new Set(array); | ||
|
||
return Array.from(set); |
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.
Could be inlined to return Array.from(new Set(array));
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.
"b": "foo", | ||
"C": 5, | ||
"d": -2, | ||
"": false, |
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.
Having a case here where the same letter appears in both upper and lower would drive the point home a little better, otherwise nice test
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 agree - I cannot add it on vacation, feel free to do it or I will do it once I return :-)
const ret: Record<string, T> = {}; | ||
const entries = Object.entries(record); | ||
|
||
for (const [key, value] of entries) { |
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.
Could inline to for (const [key, value] of Object.entries(record)) {
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.
LGTM - thank you @LionC !
Good enough for a first pass, we can clean up in the future as necessary
Co-authored-by: William Perron <hey@wperron.io>
Co-authored-by: William Perron <hey@wperron.io>
This proposal suggests adding 17 APIs (11 Array utils, 6 Record utils) as
std/collections
module. (These are extracted from the original proposal #978 by @LionC. We keep discussion on other APIs on the original PR.)Array utils (11)
Record utils (6)
In the original issue, nobody was against adding these 17. So this can be a minimal set of APIs which we could land as a first pass of
std/collections
.I'd like to land these items first if there's no strong objections to some specific items or the addition of
std/collections
entirely.