-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
RFC: make indexable collection API more uniform (keys, values, pairs) #22907
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
Conversation
|
How is |
|
|
How do you feel about supporting |
base/set.jl
Outdated
| 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)
endIt 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 ofkeysandvaluesfor arrays and sets.The second commit is just a demo of this, generalizing
findminandfindmaxso 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) = xand (maybe)keys(x) = countfrom(1)? This would allow us to keep the old behavior offindminon generic iterators with the same code. Or, we need some way to identify iterators that supportkeysandvalues, or we could decide thatfindminonly works on indexable collections.keysfor a 1-d array returns an integer range, but for other arrays returns aCartesianRange. Seems ok to me?CartesianIndexto be the "official" array index type, or should we deprecate it and just use tuples?