DataStructures.jl icon indicating copy to clipboard operation
DataStructures.jl copied to clipboard

How to efficiently modify all values of a SortedDict?

Open dpinol opened this issue 2 years ago • 2 comments

With normal Dict I can

b=Dict(3=>4)
map!(v->v*2, values(b))

b
Dict{Int64, Int64} with 1 entry:
  3 => 8

With SortedDict I can't

a=SortedDict(2=>3)
map!(v->v*2, values(a))

ERROR: MethodError: no method matching map!(::var"#7#8", ::DataStructures.SDMValIteration{SortedDict{Int64, Int64, Base.Order.ForwardOrdering}})
Closest candidates are:
  map!(::Any, ::Base.ValueIterator{<:Dict}) at dict.jl:736
  map!(::Any, ::Base.ValueIterator{<:WeakKeyDict}) at weakkeydict.jl:140
  map!(::Tf, ::SparseArrays.AbstractSparseMatrixCSC, ::Union{LinearAlgebra.Bidiagonal, LinearAlgebra.Diagonal, LinearAlgebra.LowerTriangular, LinearAlgebra.SymTridiagonal, LinearAlgebra.Tridiagonal, LinearAlgebra.UnitLowerTriangular, LinearAlgebra.UnitUpperTriangular, LinearAlgebra.UpperTriangular, SparseArrays.SparseMatrixCSC}, ::Union{LinearAlgebra.Bidiagonal, LinearAlgebra.Diagonal, LinearAlgebra.LowerTriangular, LinearAlgebra.SymTridiagonal, LinearAlgebra.Tridiagonal, LinearAlgebra.UnitLowerTriangular, LinearAlgebra.UnitUpperTriangular, LinearAlgebra.UpperTriangular, SparseArrays.SparseMatrixCSC}...) where {Tf, N} at /opt/julia/julia-1.8.0-beta3/share/julia/stdlib/v1.8/SparseArrays/src/higherorderfns.jl:1162

I can do

for (k,v) in a
       a[k]*=2
       end

but it would be less efficient

thanks

dpinol avatar May 19 '22 10:05 dpinol

This is not implemented. I am working on the sorted containers currently (https://github.com/JuliaCollections/DataStructures.jl/pull/787) but this functionality is not part of the current project. As a temporary response to this issue, I have updated the docs of that PR to explicitly mention the missing functionality. Meanwhile, the example below shows how to obtain this functionality efficiently using a loop. The point of this loop, compared to the loop in the original posting, is that semitokens can be dereferenced in O(1) operations whereas keys require O(log n) operations.

julia> s = SortedDict(3=>4)
SortedDict{Int64, Int64, Base.Order.ForwardOrdering} with 1 entry:
  3 => 4

julia> for t in onlysemitokens(s)
           s[t] *= 2
       end

julia> s
SortedDict{Int64, Int64, Base.Order.ForwardOrdering} with 1 entry:
  3 => 8

StephenVavasis avatar May 19 '22 15:05 StephenVavasis

@StephenVavasis thank you for the tip. It works great :+1:

dpinol avatar May 24 '22 14:05 dpinol