-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
paper cut: is a slice / Iterator sorted? #44370
Comments
We also shouldn't change it to be |
In the D language standard library there is also a wrapper for sorted iterables (that performs statistical tests inside its constructor), with it you can create functions that document in the code that return/accept sorted iterables. |
Just to help clarify here: slices are iterable ( |
@bluss what I meant is that we should probably implement those methods on slices as well, but that implementation should just be forwarded to the |
How would it make sense for this operation to be defined on an iterator? It would have to consume the entire iterator to get the result, leaving you only with the information that the iterator that you now can't use anymore would indeed have been sorted. |
Of course.
There are many useful algorithms that consume an iterator. Iterators don't necessarily own the items; some iterators do, some don't. If you don't want the items to get lost then don't consume an iterator that owns them. You can either copy/clone the iterator before you consume it, or you can create it again. For example, given: let v: Vec<u32> = vec![0, 1, 2, 3, 4, 5]; then this works if v.iter().is_sorted() {
for i in v.iter().map(|i| i* 2) {
println!("{}", i);
}
} but this won't compile if v.into_iter().is_sorted() { // vec is consumed here
for i in v.iter().map(|i| i * 2) {
println!("{}", i);
}
} Given that iterating over an let v: Vec<u32> = vec![0, 1, 2, 3, 4, 5];
let it = v.iter().map(|i| i* 2);
for i in it { println!("{}", i); } // it is moved here
for i in it { println!("{}", i); } // ERROR: it was already moved and that
I've added them for both convenience and consistency. The stable and unstable |
How about a non-terminal |
@the8472 itertools already has Anyhow, I am neither in favour nor opposed to doing that, but I think that discussion should belong in a different issue. This issue is about There is some prior art for |
|
That seems like a lot of complexity to avoid a single call to |
Ok, how about |
Are there any concrete use cases for a "check sorted-ness while iterating" method like is_sorted_until() or while_sorted()? I can imagine those theoretically being used for optimizations like allowing In contrast, it's quite obvious what the |
I agree that it would be good to have an easy way to check whether a slice is sorted. This exists in Go as I am a bit skeptical of the equivalent on Iterator just because the return value does not seem actionable -- you aren't going to "sort" the iterator after you find out it is not already sorted. What are some use cases for this in real code that does not involve iterating over a slice? |
I don't think it is a problem o consume the iterator, we make and consume iterators for many different tasks. For example any use of Iterator::position consumes an iterator just to answer the position question. |
Consuming an let mut v: Vec<_> = vec![1,3,2,4];
let not_sorted: bool = !v.iter().is_sorted();
if not_sorted {
v.sort(); // works
}
let not_sorted: bool = !v.iter_mut().is_sorted();
if not_sorted {
v.sort(); // works
} vs: let mut v: Vec<_> = vec![1,3,2,4];
let not_sorted: bool = !v.into_iter().is_sorted();
if not_sorted {
v.sort(); // ERROR: v has been moved
} The point of implementing this on You mentioned:
C++ If they were to work only on slices they would require a |
I would be prepared to consider a PR or RFC for this (whichever is easier). Either way please include a list of design alternatives that you evaluated -- method on slice, trait method on Iterator, free function like |
I've implemented this in this PR for the itertools crate in case someone wants to play with them: rust-itertools/itertools#261 |
Since Iterator/Itertools conflicts are pretty thorny, I'd prefer if we can merge them to Iterator in libcore directly if that's an option. But they do make good companions with wherever the |
Just FYI: I'll try to write an RFC about this in the next couple of days. I hope to summarize everything that has been said in this thread. I will link it here, once I'm finished (or update this issue if I give up :<). |
The RFC has been merged: #53485 |
I just used
binary_search
inside a loop and realized that it would be nice to check before the loop if my immutable slice was sorted. So I spent 10 minutes going through the standard library just to find out that there aren't anyis_sorted
,is_sorted_by
,is_sorted_by_key
, etc. algorithms implemented for neither slices nor iterators.We should add:
Iterator::is_sorted
Iterator::is_sorted_by
Iterator::is_sorted_by_key
and since
Iterator
is implemented for slices, we can add those methods to slices as well by just forwarding to theIterator
implementation.The text was updated successfully, but these errors were encountered: