-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Predicate versions of allequal
& allunique
#47679
Conversation
b3b9482
to
d7f2373
Compare
base/set.jl
Outdated
@@ -425,11 +425,16 @@ end | |||
|
|||
""" | |||
allunique(itr) -> Bool | |||
allunique(f, xs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very nitpicky, but using different names for the iterator seems confusing (even though it's maybe helpful for the current definition of this second form).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a bit ugly, I think I wanted to say itr = (f(x) for x in xs)
below... but can say it another way.
Think it's OK to roll these definitions into the same docstring? They could be separate but probably that's just more text to dig through.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See if you like 21961ec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes looks good. An alternative could be
""""
allunique([f=identity], itr) -> Bool
Return `true` if all values from `(f(x) for x in itr)` are distinct when compared with [`isequal`](@ref).
"""
(but that makes the simpler case (allunique(itr)
) more difficult to understand...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it should warn you that how many times f
is called is regarded as an implementation detail? It may not be called at all (if length 1 is known) and it may be called even after a non-unique elements has been seen (as _indexed_allunique(collect(C))
makes the whole array & then checks).
Not sure how surprising that is. In my head at least, f
ought to be fairly cheap, because you are obviously throwing away what it returns, and probably pure too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
724f048 adds such a note.
d7f2373
to
21961ec
Compare
e019983
to
123cf6b
Compare
d711f6e
to
1a20976
Compare
Would be nice to have this. Is there something missing on this PR, or is this ready to be merged? |
d99c478
to
e14eb0d
Compare
Pre-1.11 bump? |
LGTM. I polished up the commit message a bit on merge. |
Closes #47005, and does the same for
allunique
.First, a33ac25 uses
Iterators.peel
to improveallequal(itr)
as suggested by @jlapeyre in here: #47005 (comment) .After that,
allequal(f, xs) = allequal(f(x) for x in xs)
should never callf
twice on the samex
, nor more times than necessary.For
allunique
, at present this has a path which collects short iterators (<32) as this is faster than making aSet
. Thus callingallunique(f(x) for x in xs)
will sometimes callf
more times than it has to. This PR doesn't change that, just adds a methodallunique(f, xs)
.Since generators tend to have eltype
Any
, it pays to useSet{@default_eltype(C)}()
now. I think this ought to be safe.Finally, methods
allequal(f, xs::Tuple)
andallunique(f, xs::Tuple)
seem to be worthwhile. This gist times a few variants.