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

The return of the GroupBy and GroupByMut iterators on slice #79895

Merged
merged 14 commits into from
Dec 31, 2020

Conversation

Kerollmops
Copy link
Contributor

According to rust-lang/rfcs#2477 (comment), I am opening this PR again, this time I implemented it in safe Rust only, it is therefore much easier to read and is completely safe.

This PR proposes to add two new methods to the slice, the group_by and group_by_mut. These two methods provide a way to iterate over non-overlapping sub-slices of a base slice that are separated by the predicate given by the user (e.g. Partial::eq, |a, b| a.abs() < b.abs()).

let slice = &[1, 1, 1, 3, 3, 2, 2, 2];

let mut iter = slice.group_by(|a, b| a == b);
assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next(), None);

An RFC was open 2 years ago but wasn't necessary.

@Kerollmops
Copy link
Contributor Author

Kerollmops commented Dec 10, 2020

Hey @rylev,

Thanks for the comment, I changed the tests a little bit, however, do you have an idea on how I should fix this CI tidy issue? The file is now too long what should I do? Create a new one just for those two structs?

tidy error: /checkout/library/core/src/slice/iter.rs: too many lines (3133) (add // ignore-tidy-filelength to the file to suppress this error)

@rylev
Copy link
Member

rylev commented Dec 10, 2020

@Kerollmops I'm not sure. I'd also be curious to know what the right move is here (either to suppress the warning or to break up the file).

@lcnr
Copy link
Contributor

lcnr commented Dec 10, 2020

I think it's fine to just suppress the warning for now. Splitting slice::iter into submodules is something that's easier in a followup PR

@lcnr
Copy link
Contributor

lcnr commented Dec 10, 2020

cc @rust-lang/infra bors didn't assign anyone here

r? @m-ou-se

@camelid camelid added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 18, 2020
@camelid
Copy link
Member

camelid commented Dec 18, 2020

bors didn't assign anyone here

FYI I think you mean rust-highfive. Probably the bot was being redeployed or something.

@camelid camelid added A-iterators Area: Iterators A-slice Area: `[T]` T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Dec 18, 2020
Copy link
Member

@m-ou-se m-ou-se left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This looks great!

2 years ago

Apologies again! We're working on streamlining our processes. This shouldn't happen again. :)

Create a new one just for those two structs?

We should probably split files like these into more submodules at some point (just like #78934 does). A separate file for these new structs would be good (e.g. slice/iter/group_by.rs). But leaving that for later is also fine. Then it can be done together with the rest of the file.


Only one thing left before we can merge this:

Can you open a tracking issue for this, and add its number in the unstable attributes? Thanks!

(By the way, feel free to rebase/squash commits.)

@m-ou-se m-ou-se added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 30, 2020
@Kerollmops
Copy link
Contributor Author

I just created the tracking issue, added it to the files, and squashed everything.

No worries about the 2 years waiting time, I implemented it myself, it was quite fun! I also benchmarked it and the full safe Rust version is a little bit slower than the unsafe one.

@m-ou-se
Copy link
Member

m-ou-se commented Dec 31, 2020

Thanks!

@bors r+

@bors
Copy link
Contributor

bors commented Dec 31, 2020

📌 Commit 8b53be6 has been approved by m-ou-se

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 31, 2020
Comment on lines +1213 to +1214
/// Returns an iterator over the slice producing non-overlapping runs
/// of elements using the predicate to separate them.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this should have a stronger mark on the fact that it only groups consecutive items, especially with such an ambiguous function name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say 'runs of elements' already implies that. But I'd be happy to review your PR if you have an idea on how to improve the wording. Improvements to documentation are always welcome. :)

Comment on lines +1225 to +1232
/// let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
///
/// let mut iter = slice.group_by(|a, b| a == b);
///
/// assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
/// assert_eq!(iter.next(), Some(&[3, 3][..]));
/// assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
/// assert_eq!(iter.next(), None);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this gives a false perception that it groups the same items, no matter where they are. Would probably be better if the same element appeared multiple times in different groups, for example:

Suggested change
/// let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
///
/// let mut iter = slice.group_by(|a, b| a == b);
///
/// assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
/// assert_eq!(iter.next(), Some(&[3, 3][..]));
/// assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
/// assert_eq!(iter.next(), None);
/// let slice = &[1, 1, 1, 3, 3, 2, 2, 2, 1, 1];
///
/// let mut iter = slice.group_by(|a, b| a == b);
///
/// assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
/// assert_eq!(iter.next(), Some(&[3, 3][..]));
/// assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
/// assert_eq!(iter.next(), Some(&[1, 1][..]));
/// assert_eq!(iter.next(), None);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your point but I find the second example clear enough and let the user understand that the split are based on the specified function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if someone skips the second example? You could argue that's the user's fault, but I'd like to make this as much foolproof as we can

@bors
Copy link
Contributor

bors commented Dec 31, 2020

⌛ Testing commit 8b53be6 with merge b33e234...

@bors
Copy link
Contributor

bors commented Dec 31, 2020

☀️ Test successful - checks-actions
Approved by: m-ou-se
Pushing b33e234 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Dec 31, 2020
@bors bors merged commit b33e234 into rust-lang:master Dec 31, 2020
@rustbot rustbot added this to the 1.51.0 milestone Dec 31, 2020
This was referenced Dec 31, 2020
@Kerollmops
Copy link
Contributor Author

Thank you for the review @m-ou-se :)

@Kerollmops Kerollmops deleted the slice-group-by branch December 31, 2020 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-iterators Area: Iterators A-slice Area: `[T]` merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants