Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign uppaper cut: is a slice / Iterator sorted? #44370
Comments
gnzlbg
changed the title
paper cut: check if a slice is sorted before using binary search
paper cut: is a slice / Iterator sorted?
Sep 6, 2017
gnzlbg
referenced this issue
Sep 6, 2017
Closed
allow standard library functions to check expensive pre-/postconditions #44371
This comment has been minimized.
This comment has been minimized.
|
We also shouldn't change it to be |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
leonardo-m
commented
Sep 6, 2017
|
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. |
This comment has been minimized.
This comment has been minimized.
Just to help clarify here: slices are iterable ( |
This comment has been minimized.
This comment has been minimized.
|
@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 |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
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 movedand that
I've added them for both convenience and consistency. The stable and unstable |
This comment has been minimized.
This comment has been minimized.
the8472
commented
Sep 7, 2017
|
How about a non-terminal |
This comment has been minimized.
This comment has been minimized.
|
@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 |
This comment has been minimized.
This comment has been minimized.
the8472
commented
Sep 7, 2017
|
|
This comment has been minimized.
This comment has been minimized.
|
That seems like a lot of complexity to avoid a single call to |
This comment has been minimized.
This comment has been minimized.
the8472
commented
Sep 7, 2017
|
Ok, how about |
alexcrichton
added
C-feature-request
T-libs
labels
Sep 7, 2017
TimNN
added
the
A-collections
label
Sep 17, 2017
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
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? |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
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 |
dtolnay
added
C-feature-accepted
and removed
C-feature-request
labels
Nov 19, 2017
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
I've implemented this in this PR for the itertools crate in case someone wants to play with them: bluss/rust-itertools#261 |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
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 :<). |
LukasKalbertodt
referenced this issue
Feb 25, 2018
Merged
RFC: Add `is_sorted` to the standard library #2351
This comment has been minimized.
This comment has been minimized.
|
The RFC has been merged: #53485 |
gnzlbg commentedSep 6, 2017
•
edited
I just used
binary_searchinside 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_sortedIterator::is_sorted_byIterator::is_sorted_by_keyand since
Iteratoris implemented for slices, we can add those methods to slices as well by just forwarding to theIteratorimplementation.