From 80a2f3bb678323791af8d3c1f97263f2af770d1a Mon Sep 17 00:00:00 2001 From: Andy Ferris Date: Sat, 6 Feb 2021 15:27:33 +1000 Subject: [PATCH] Enable `getproperty` for `Symbol` keys --- Project.toml | 2 +- README.md | 23 +++++++++++++++++++++++ src/Indices.jl | 4 ++-- src/indexing.jl | 10 +++++----- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/Project.toml b/Project.toml index 7e244ef..9284e1c 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ authors = ["Andy Ferris "] name = "Dictionaries" uuid = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" -version = "0.3.7" +version = "0.3.8" [deps] Indexing = "313cdc1a-70c2-5d6a-ae34-0150d3930a38" diff --git a/README.md b/README.md index 4a264b9..b54f3ef 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,29 @@ julia> delete!(dict, "d") Note that `insert!` and `delete!` are precise in the sense that `insert!` will error if the index already exists, and `delete!` will error if the index does not. The `set!` function provides "upsert" functionality ("update or insert") and `unset!` is useful for removing an index that may or may not exist. +#### Dictionaries with `Symbol` keys + +If the keys of a dictionary are `Symbol`s, then it is possible to use Julia's `getproperty` syntax sugar to access elements. + +```julia +julia> dict = Dictionary([:a, :b, :c], [1, 2, 3]) +3-element Dictionary{Symbol,Int64} + :a │ 1 + :b │ 2 + :c │ 3 + +julia> dict.b +2 + +julia> dict.a = 100; dict +3-element Dictionary{Symbol,Int64} + :a │ 100 + :b │ 2 + :c │ 3 +``` + +This property makes them good substitutes for `NamedTuple`s, or for storing and accessing the rows or columns of a table. + ### Working with dictionaries Dictionaries can be manipulated and transformed using a similar interface to Julia's built-in arrays. The first thing to note is that dictionaries iterate values, so it easy to perform simple analytics on the dictionary values. diff --git a/src/Indices.jl b/src/Indices.jl index 43431c4..f7eabe9 100644 --- a/src/Indices.jl +++ b/src/Indices.jl @@ -505,7 +505,7 @@ function __distinct!(indices::AbstractIndices, itr, s, x_old) end function randtoken(rng::Random.AbstractRNG, inds::Indices) - if inds.holes === 0 + if _holes(inds) === 0 return (0, rand(rng, Base.OneTo(length(inds)))) end @@ -513,7 +513,7 @@ function randtoken(rng::Random.AbstractRNG, inds::Indices) range = Base.OneTo(length(_hashes(inds))) while true i = rand(rng, range) - if inds.hashes[i] !== deletion_mask + if _hashes(inds)[i] !== deletion_mask return (0, i) end end diff --git a/src/indexing.jl b/src/indexing.jl index d7662a3..75ce793 100644 --- a/src/indexing.jl +++ b/src/indexing.jl @@ -48,11 +48,11 @@ end ## getproperty is equivalent to indexing with a `Symbol` -# @propagate_inbounds Base.getproperty(d::AbstractDictionary, s::Symbol) = d[s] -# @propagate_inbounds function Base.setproperty!(d::AbstractDictionary, s::Symbol, x) -# d[s] = x -# return x -# end +@propagate_inbounds Base.getproperty(d::AbstractDictionary, s::Symbol) = d[s] +@propagate_inbounds function Base.setproperty!(d::AbstractDictionary, s::Symbol, x) + d[s] = x + return x +end ## Non-scalar indexing