Skip to content
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

"Chunking" by an arbitrary condition #1

Closed
towerofnix opened this issue Jan 14, 2024 · 3 comments
Closed

"Chunking" by an arbitrary condition #1

towerofnix opened this issue Jan 14, 2024 · 3 comments

Comments

@towerofnix
Copy link

Hey, this is mostly a meta question, because I understand that chunks and windows are purely based on counting. But a relatively common pattern in my code is to for example divide a list according to one of a number of conditions, comparing the current item with the previous:

// Divide tracks along boundaries where the first and second
// are in a different album or on a different date:
dividedTracks =
  chunk(tracks, (track1, track2) =>
    track1.album !== track2.album ||
    track1.date !== track2.date)

// In:
[{name: "k", album: "A", date: 123},
 {name: "o", album: "A", date: 123},
 {name: "a", album: "B", date: 123},
 {name: "l", album: "B", date: 124},
 {name: "a" album: "B", date: 124}]

// Out:
[[{name: "k", album: "A", date: 123}, {name: "o", album: "A", date: 123}],
 [{name: "a", album: "B", date: 123}],
 [{name: "l", album: "B", date: 124}, {name: "a", album: "B", date: 124}]]

When I heard about the Array Grouping proposal, I thought it might be what I was looking for. But that behavior is different - it's about shuttling all the items from an array into particular buckets. It doesn't maintain the sequence. So what I'm looking for feels like somewhat "iterator-y" behavior, but I don't know if this kind of operation has any primitive in recent proposals, and I have no idea what it'd be called in other programming languages, either!

Here's a reduce-based implementation:

chunk = (array, condition) =>
  array.reduce(
    (accumulator, item, index) =>
      (index === 0
        ? [[item]]
        : (condition(array[index - 1], item)
            ? [...accumulator, [item]]
            : [...accumulator.slice(0, -1),
               accumulator.at(-1).concat([item])])),
    []);

And here's the implementation we actually use (which mutates/reuses the working array instead).

Sorry this isn't directly relevant to this proposal! It's just similar terminology to what i've pretty arbitrarily come up with; I figure there's at least a chance someone visiting this proposal might be looking for something similar.

By the way, I came to this proposal (eventually) from tc39/proposal-array-grouping#53 — I wanted to bring this up because the issue specifically brings up using an arbitrary condition (they just happen to use a count-value-by-two, which is vaguely similar to chunks). @jridgewell pointed out that there are two possible behaviors (since the issue was ambiguous) and while one is superfluous with the presence of groupBy, the other is unique behavior "similar to python's itertools.groupby", which they said had been discussed in committee.

Is there a different proposal I should head towards, or is that idea yet to be explored in a dedicated proposal, or generally taken off the table by committee discussion for other reasons?

@bakkot
Copy link
Contributor

bakkot commented Jan 14, 2024

The operation you're thinking of is, confusingly enough, also named groupBy in Haskell. Python's groupBy is slightly different in that (like Object.groupBy) it instead takes a mapper and compares results of that mapper using equality, which ends up being similar in practice.

I might call it groupRuns or something? But no, there's no other proposal for it at the moment.

@michaelficarra
Copy link
Member

@towerofnix While only TC39 delegates can bring a proposal to committee, anyone from the community may author a proposal. If you feel strongly enough about a Data.List.groupBy-like function for iterators, you can follow the pattern I have used with my iterator helper follow-up repos and create a proposal yourself. Then you can share it on Matrix or Discourse and hopefully get someone to champion it for you.

Anyway, since this isn't related to the chunking problem that this proposal is trying to solve, closing.

@michaelficarra michaelficarra closed this as not planned Won't fix, can't repro, duplicate, stale Jan 16, 2024
@towerofnix
Copy link
Author

Thanks a bunch for the answers, both. I'm not likely going to author one as I don't feel exceptionally strong about it and generally am busy and not too interested in the social aspects of making a proposal come together. I'll consider it of course (and the guidance from you helps), but just wanted to note that this idea is more than open for anyone else to prepare and share a proposal for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants