# Wrapping iterator, caching intermediate transformation

**URL:** <https://discourse.julialang.org/t/wrapping-iterator-caching-intermediate-transformation/38229>\
**Category:** General Usage\
**Created:** [April 26, 2020, 9:04am UTC](https://discourse.julialang.org/t/wrapping-iterator-caching-intermediate-transformation/38229 "2020-04-26T09:04:37Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![phg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phg/32/17184_2.png) [@phg](https://discourse.julialang.org/u/phg)\
**Post date:** [April 26, 2020, 9:04am UTC](https://discourse.julialang.org/t/wrapping-iterator-caching-intermediate-transformation/38229/1 "2020-04-26T09:04:37Z")

</div>

I want to wrap a dictionary in a data structure that lets you iterate over it in sorted order. Is there any more elegant solution than the following?

```julia
struct Graph
    # For example's sake
    statements::Dict{Int, Int}
end

function _makewrappediter(graph::Graph)
    stmts = sort(graph.statements)
    return stmts, iterate(stmts)
end

function Base.iterate(graph::Graph, (stmts, iter)=_makewrappediter(graph))
    if !isnothing(iter)
        el, state = iter
        return el, (stmts, iterate(stmts, state))
    else
        return nothing
    end
end

```

By “more elegant” I mean some (syntactic?) trickery that let’s one get rid of the helper function and manual repetition of the `nothing` check.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [April 27, 2020, 7:37am UTC](https://discourse.julialang.org/t/wrapping-iterator-caching-intermediate-transformation/38229/2 "2020-04-27T07:37:48Z")

</div>

Maybe `SortedDict` from DataStructures.jl ([Sorted Containers · DataStructures.jl](https://juliacollections.github.io/DataStructures.jl/latest/sorted_containers/)) is a more appropriate choice for your task?

---

<div class="post-metadata">

**Author:** ![phg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phg/32/17184_2.png) [@phg](https://discourse.julialang.org/u/phg)\
**Post date:** [April 27, 2020, 5:17pm UTC](https://discourse.julialang.org/t/wrapping-iterator-caching-intermediate-transformation/38229/3 "2020-04-27T17:17:29Z")

</div>

That’s a good suggestion, but in this case the struct is merely a container for several dicts that get updated often, and one of them is iterated over only rarely (i.e., once at the end of processing).

But the semantics are not really in question, it is the iterator implementation I seek improvement for.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [April 27, 2020, 7:55pm UTC](https://discourse.julialang.org/t/wrapping-iterator-caching-intermediate-transformation/38229/4 "2020-04-27T19:55:02Z")

</div>

Should this code even work? There is not method sort for `Dict{Int, Int}`.

```julia
> d = Dict{Int, Int}(1 => 100, 2 => -200);
> sort(d)
ERROR: MethodError: no method matching sort(::Dict{Int64,Int64})

```

Your `sort(graph.statements)` should be doing what?

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [April 27, 2020, 10:25pm UTC](https://discourse.julialang.org/t/wrapping-iterator-caching-intermediate-transformation/38229/5 "2020-04-27T22:25:59Z")

</div>

@phg Is there a reason to not just iterate over `sort(graph.statements)`? I don’t see a way to avoid an additional check for `nothing` in a wrapped iterator. I would probably go with a sorted array of keys instead of a sorted dictionary, like that

```julia
function Base.iterate(graph::Graph, (i, sortedkeys)=(1, Int[]))
    stmts = graph.statements
    isempty(stmts) && return nothing
    if i == 1
        empty!(sortedkeys)
        append!(sortedkeys, keys(stmts))
        sort!(sortedkeys)
    end
    if i in eachindex(sortedkeys)
        return stmts[sortedkeys[i]], (i+1, sortedkeys)
    else
        return nothing
    end
end

```

But the `nothing` check is just replaced by `in eachindex()` check.  
@Henrique_Becker OrderedCollections.jl overloads `sort` for dictionaries, returning `OrderedDict`.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [April 28, 2020, 12:47am UTC](https://discourse.julialang.org/t/wrapping-iterator-caching-intermediate-transformation/38229/6 "2020-04-28T00:47:12Z")

</div>

FYI, it looks like `sort(::Dict)` will be gone at some point (to avoid type-piracy) [https://github.com/JuliaCollections/OrderedCollections.jl/issues/25](https://github.com/JuliaCollections/OrderedCollections.jl/issues/25). It’s better to write `sort!(collect(graph.statements))`.

---

<div class="post-metadata">

**Author:** ![phg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phg/32/17184_2.png) [@phg](https://discourse.julialang.org/u/phg)\
**Post date:** [April 28, 2020, 10:35am UTC](https://discourse.julialang.org/t/wrapping-iterator-caching-intermediate-transformation/38229/7 "2020-04-28T10:35:45Z")

</div>

Ha! I didn’t realize at all that `sort(::Dict)` is from OrderedCollections! I thought that’s in Base. Maybe I’ll just stick with the SortedDict suggestion, then.

But it still bothers me that there’s no nice equivalent to the short

```python
def iterate(self):
    yield from sort_dict_by_key(self.statements)

```

or similar in Python.
