-
Notifications
You must be signed in to change notification settings - Fork 5
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
Suggestion to add Array#partition as well #2
Comments
For the note, underscore |
Thanks added to Related |
Also RxJS |
Hi @MaxGraey, I think partition needs to be its own proposal. It's certainly related to |
Reopening to discuss. @MaxGraey, do you know of any libraries/projects/etc that are using partition? /cc @michaelficarra |
edit: Sorry, I didn't see that these were mentioned in earlier comments. |
@michaelficarra yup. Are you aware of projects using them, though? |
@jridgewell we use partition at my work rather extensively, typically around usage of https://github.com/graphql/dataloader, which can often provide arrays of the type The source is not available for this usage, but here are some real-life examples that I've copied: const [rejectedReviews, approvedReviews] = partition(allReviews, (review) => review.rejectionReasonCode != null); // Type-safety of this function ensures well-typed `errors` and `items` below
function isError(candidate: unknown): candidate is Error {
return candidate instanceof Error;
}
const itemsAndErrors = await dataLoader.loadMany(ids);
const [errors, items] = partition(itemsAndErrors, isError); |
btw lodash.partition has |
I guess query exactly const partition = require('lodash.partition');
const { partition } = require('lodash'); and etc |
As a radical proposal, what about implementing const [, cd] = [a,b,c,d].partition((_, index) => index >= 2)
// is equivalent to...
const cd = [a,b,c,d].filterOut((_, index) => index >= 2) A sufficiently-clever implementation should ideally be able to recognize this situation, and internally fall back to a more-efficient |
@schmod Good point! const [ab] = [a,b,c,d].partition((_, index) => index >= 2);
// which equivalent to
const ab = [a,b,c,d].filterOut((_, index) => index >= 2); |
I find Then, is it Then there's also the query data. Use of While |
I think |
That's true. const lessThan2 = arr.filter(val => !(val >= 2));
// or const [lessThan2] = arr.groupBy(val => Number(val >= 2)); much less expressive than const lessThan2 = arr.filterOut(val => val >= 2); same as: const [lessThan2, greaterOrEqThan2] = arr.groupBy(val => Number(val >= 2)); less expressive than const [lessThan2, greaterOrEqThan2] = arr.partition(val => val >= 2); |
You have to sort of intricately "know" what order the tuple returns the values in, it might be better to return a struct:
ex: const {
in: greaterThanOrEq2,
out: lessThan2
} = arr.partition(val => val >= 2); Although, thinking about it, |
Oh, then how about |
it also contradicts the generally accepted conventions already in JS: Main advantages of array tuple you could always skip unnecessary part: const [, cd] = [a,b,c,d].partition((_, index) => index >= 2)
const [ab] = [a,b,c,d].partition((_, index) => index < 2) but also you could this: const { 1: cd } = [a,b,c,d].partition((_, index) => index >= 2)
const { 0: ab } = [a,b,c,d].partition((_, index) => index < 2) with objects: const { out: cd } = [a,b,c,d].partition((_, index) => index >= 2)
const { in: ab } = [a,b,c,d].partition((_, index) => index < 2) |
You can do the same with the struct, just don't use the other property from the struct. const {
in: greaterOrEqThan2,
out: lessThan2
} = arr.partition(val => val >= 2); vs const { out: lessThan2 } = arr.partition(val => val >= 2);
They return arrays of key-value pairs, in contrast, here would you want to say that there is an association between what was filtered in and out? I would say "no," because we are intentionally trying to separate them into two totally separate categories, therefore you wouldn't want to pair them. But actually, returning a tuple seems more like the opposite of Regardless, I personally would support How about getting a |
I think partition could be generalize more and include slide, stride and chunk features. See this talk: |
Well, I finally needed a partition today: ampproject/amphtml@dc3db0e#diff-d06fcad39d9e58f050ba123f5f506cbc1a8865fde8a6016c4dc32bbfc71d06c9R256-R264 |
I've several times done stuff like this, so it may be worth doublechecking for that kind of pattern: const foos = items.filter(item => item.type === "foo")
const bars = items.filter(item => item.type !== "foo") And of course there's several ways this could be expressed, each of which I've seen personally in the wild:
|
@isiahmeadows I'm not sure what you're trying to point out, can you clarify? Your code example is equivalent to the following: const partitioner = item => item.type === "foo";
const foos = items.filter(partitioner);
const bars = items.filter(item => !partitioner(item)); Which is the current problem that we would like to fix.
I don't get this right away, can you give an example?
As long as they are mutually exclusive, the original proposal should work just fine. As for your example, would you want a method that takes two comparer functions? const [
foos,
bars
] = items.partition(
item => item.type === "foo",
item => item.type === "bar"
); I feel like that could easily be extended to accept N functions, and return an array of N, storing all values that the function returned a truthy value for, but really seems like it should be a user-implemented library solution. |
@isiahmeadows is demonstrating that they needed both the "filtered out" and the "filtered in" at the same time, which
This seems a bit more complicated than a generic |
@jridgewell hey, maybe already makes sense to add it to the proposal? Seems it's really required and the community wanna it. |
Absolutely not. It overcomplicates the algorithm, the understanding of purpose, and overall documentation of this hypothetical method.
Please, let's not overcomplicate things. It will be difficult to know when to teach, when to use, and whether it's efficient enough to bother with. If you want to worry about those things, then use an NPM package. I don't want to see that canonicalized within ECMAScript. |
@ckknight for the previous 5 months |
@ckknight I remember how this approach is "useful" on "leftpad" example |
I am in favor of having a simple, useful |
@ckknight so why do you think that I mean something else? |
@ckknight The algorithm would require about 3 more lines of ES spec text, compared to filter/filterOut, one line to call an abstract operation to get the array species constructor, an extra variable declaration using that constructor, the line with "let k be k + 1" can be removed, as it is now always pushing to an array, and the creation of the structure to return. Regardless, the current Array#filter discards useful data that developers intend to use. Array#filter feels broken, there's no question about it. |
I also needed a
Yah, I can bring up both at the next meeting. |
I also prefer |
The spec text currently includes |
|
Examples
Basics:
Immutable (out of place) Quick Sort:
Efficient and correct implementation usually not trivial:
or
or based this proposal:
Related
OCaml: List.partition
Haskell: Data.List.partition
Lodash: _.partition
RxJS: RxJS/partition
Kotlin: Array.partition
The text was updated successfully, but these errors were encountered: