-
Notifications
You must be signed in to change notification settings - Fork 584
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
feat(collections): add filterNotNullish #1168
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.
I left some comments - the major one being that we should use a builtin internally here, as it does not create additional overhead.
collections/README.md
Outdated
|
||
### filterNotNullish | ||
|
||
Returns all elements in the given collection that are not nullish |
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 we can be clear here and say "are neither null
or undefined
" to be very clear.
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.
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 👌
collections/filter_not_nullish.ts
Outdated
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. | ||
|
||
/** | ||
* Returns all elements in the given collection that are not nullish |
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.
Same here
collections/filter_not_nullish.ts
Outdated
* ``` | ||
*/ | ||
export function filterNotNullish<T>( | ||
collection: readonly T[], |
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.
We have settled on array
for these arguments in all the other functions, we should do the same here:
collection: readonly T[], | |
array: readonly T[], |
collections/filter_not_nullish.ts
Outdated
const result: NonNullable<T>[] = []; | ||
|
||
for (const current of collection) { | ||
if (current !== undefined && current !== null) { | ||
result.push(current as NonNullable<T>); | ||
} | ||
} | ||
|
||
return 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 think simply using builtin filter
will likely be faster because of potential magic v8 optimizations and it will not have any additional memory overhead in this case:
const result: NonNullable<T>[] = []; | |
for (const current of collection) { | |
if (current !== undefined && current !== null) { | |
result.push(current as NonNullable<T>); | |
} | |
} | |
return result; | |
return array.filter((it) => it !== undefined && it !== null); |
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.
@LionC since we used for..of
in every function I wanted to keep it consistent. so I should use built-in functions whenever it makes sense?
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.
In the other functions, we use for..of
to optimise for performance overhead, since the builtins like .map
and .filter
iterate through he whole array
and create a copy, when it could be implemented more efficiently.
Here, however, the runtime complexity and memory overhead are exactly the same, so using the builtin is fine and will likely be faster because of optimizations.
I want to note that there has been discussion surrounding this function in the initial proposal because people felt like it is too simple. However, I want to add, that almost everyone who complained about it in the initial discussion proposed a "trivial" replacement for it in the form of This implementation also gets types right, which typescript does not even for Also, same as always, kotlin has it and it is being used a lot, yada yada^^ I want to make sure that discussion around this happens properly, so be prepared for this being PR being open for a moment :-) |
@LionC updated. |
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, pinging @kt3k
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.
Hey @majidsajadi. Thanks for the PR.
I am not going to merge this PR, because I think we are starting to scope creep std/collections here. This PR adds nearly 100 lines of code we need to maintain. We have removed a lot more complex functions from std because of triviality (e.g. denoland/deno#7256).
This is a 1 line function that takes about 30 seconds to write by hand. Going to deno.land/std and finding this function to import takes significantly longer than 30 seconds.
Some more background why trivial functions like these should be written by hand for each scenario:
- What if I want to filter only undefined (not null)?
- What if I want to filter undefined + numbers?
- What if I want to filter all falsy values?
Merging this PR sets the precedent that trivial functions like ones described above would be accepted into std.
This PR adds
filterNotNullish
to thecollections
module