-
-
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
RFC: make indexable collection API more uniform (keys, values, pairs) #22907
Conversation
How is |
|
How do you feel about supporting |
base/set.jl
Outdated
@@ -8,6 +8,9 @@ mutable struct Set{T} <: AbstractSet{T} | |||
end | |||
Set() = Set{Any}() | |||
|
|||
# a set iterates its values | |||
values(s::AbstractSet) = s |
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.
Is keys(s)
supposed to return an error?
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.
getindex is
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.
So the new findmin
now errors on sets? I think that makes sense.
Would it be better to use |
51be6ac
to
4931ded
Compare
So I think |
That's an issue that affects all find/search functions, not only See also #14086 (comment) and following comments, and the short mention about this (second bullet of the section) in the Search & Find Julep. |
My gut reaction would be to:
I think this sort of scheme would be okay propagating through to the find/etc APIs. You would opt-in to a linear index for a multidimensional array by simply doing a |
I would be ok with that. We could also add something like
allowing Related: #20684 |
25915e7
to
68ed301
Compare
OK, I'm starting to get a handle on this. Here's what I did:
However, I have not tackled the |
You could probably get rid of |
They don't do the same thing ---
This is a possible design, but it conflicts with a generic definition of |
Right on While you're at this and thinking about |
I think |
To offer a dissenting voice here - have we considered going the other direction, making Or, another way to think of this is that If the set of things that I can index with are called Note that I do strongly support that we unify associatives and arrays and other containers that use |
Please don't do that – for (i, x) in enumerate(itr)
i > 1 && print(io, ", ")
print(io, x)
end It doesn't require the length of the iterable, which the way I was doing this before did. |
I agree, I would be perfectly happy to rename Especially with dictionaries, people very often use "key/value" terminology, so it's nice to have |
I agree re: |
Idea: move |
68ed301
to
7c1c298
Compare
OK, I think this is ready to go. The function is still called I've updated all |
7c1c298
to
8a7f46e
Compare
What's up with the build failures? |
8a7f46e
to
5f7efae
Compare
In a way that's a good sign, since it means the new behavior gives what that code actually wanted, without needing to call |
Would it make sense to add a deprecated |
Makes the return type change of #22907 less breaking by allowing the common pattern `ind2sum(size(a), indmax(a))` to still work.
Makes the return type change of #22907 less breaking by allowing the common pattern `ind2sub(size(a), indmax(a))` to still work.
+1 for this change but type inference on
v0.7:
|
Ok so I looked at the new implementation of this PR. The obvious solution is to also use the A second question about the following lines: pairs(::IndexLinear, A::AbstractArray) = IndexValue(A, linearindices(A))
pairs(::IndexCartesian, A::AbstractArray) = IndexValue(A, CartesianRange(indices(A)))
# faster than zip(keys(a), values(a)) for arrays
pairs(A::AbstractArray) = pairs(IndexCartesian(), A)
pairs(A::AbstractVector) = pairs(IndexLinear(), A) Why not just |
Actually also for |
Ok here are a few possible solutions that seem to work: I can prepare a PR for any of them, once a concensus is reached:
pairs(collection) = Generator(=>, keys(collection), values(collection)) with pairs(collection) = Generator(=>, zip(keys(collection), values(collection))) and add a definition This seems to fix the type instability with dicts and tuples.
Replace |
Actually, solution 4 is even simpler: pairs(collection) = (k=>v for (k,v) in zip(keys(collection), values(collection)) This looks like it should be identical to the current definition pairs(collection) = Generator(=>, keys(collection), values(collection)) yet the former is inferable, the latter is not. Not sure why that is, but I expect that changing the definition to the first one is something everybody could agree on? |
I think this can be fixed by adding an extra |
I've just tried adding pairs(collection) = Generator(kv->(kv[1]=>kv[2]), zip(keys(collection), values(collection))) seems to work though. I was just preparing a PR. |
Should be fixed by #24145. |
So what should I use instead of |
Please ask questions on the Julia discourse discussion forum. |
The first commit adds
pairs
, which is supposed to return a key-value iterator for any indexable collection, and adds methods ofkeys
andvalues
for arrays and sets.The second commit is just a demo of this, generalizing
findmin
andfindmax
so that the identityfindmax(array) == findmax(Dict(pairs(array)))
holds. This is a breaking change, since previously these functions only returned indices 1:n.Discussion questions:
values(x) = x
and (maybe)keys(x) = countfrom(1)
? This would allow us to keep the old behavior offindmin
on generic iterators with the same code. Or, we need some way to identify iterators that supportkeys
andvalues
, or we could decide thatfindmin
only works on indexable collections.keys
for a 1-d array returns an integer range, but for other arrays returns aCartesianRange
. Seems ok to me?CartesianIndex
to be the "official" array index type, or should we deprecate it and just use tuples?