# Indexing \`OrderedDict\`s by index instead of key

**URL:** <https://discourse.julialang.org/t/indexing-ordereddict-s-by-index-instead-of-key/77846>\
**Category:** Internals & Design\
**Tags:** indexing, dictionary\
**Created:** [March 14, 2022, 5:54am UTC](https://discourse.julialang.org/t/indexing-ordereddict-s-by-index-instead-of-key/77846 "2022-03-14T05:54:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [March 14, 2022, 5:54am UTC](https://discourse.julialang.org/t/indexing-ordereddict-s-by-index-instead-of-key/77846/1 "2022-03-14T05:54:41Z")

</div>

One can access values of `OrderedDict`s by their index by exposing the internal `vals` field, like so:

```julia
julia> od = sort(Dict('a'=>'A', 'b'=>'B'))
OrderedCollections.OrderedDict{Char, Char} with 2 entries:
  'a' => 'A'
  'b' => 'B'

julia> od.vals[2]
'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)

```

But this doesn’t feel like the “front-end” way of doing this — I always find myself wanting to write `values(od)` and being surprised when the `ValueIterator` object it returns doesn’t support indexing.

Should I submit a PR to [`OrderedCollections.jl`](https://github.com/JuliaCollections/OrderedCollections.jl) and implement `getindex(::ValueIterator{<:OrderedDict}, …)` so that `values(od)[2]` works?

I only hesitate because `values` does’t seem to return `getindex`-able objects normally. I’m not sure if that’s by design.

---

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [March 14, 2022, 6:30am UTC](https://discourse.julialang.org/t/indexing-ordereddict-s-by-index-instead-of-key/77846/2 "2022-03-14T06:30:19Z")

</div>

I’m over-thinking it. [Here is a PR](https://github.com/JuliaCollections/OrderedCollections.jl/pull/84), I’ll see what the maintainers think.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [March 14, 2022, 10:08am UTC](https://discourse.julialang.org/t/indexing-ordereddict-s-by-index-instead-of-key/77846/3 "2022-03-14T10:08:31Z")

</div>

A generic approach would be to implement a `collect` which allows for certain index ranges, like:

```julia
collect(values(d),startindex,lastindex)

```

which doesn’t allocate the complete array like in:

```julia
collect(values(d))[startindex:lastindex]

```

Using internal `d.vals` is problematic as, e.g. it does work for `OrderedDict` only by fortune, see:

```julia
julia> d=Dict("a" => "12345", "b" => "23345", "c" => "654645");

julia> d.vals
16-element Vector{String}:
 #undef
 #undef
 #undef
    "654645"
 #undef
 #undef
 #undef
 #undef
    "23345"
 #undef
 #undef
 #undef
 #undef
    "12345"
 #undef
 #undef

```

---

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [March 14, 2022, 9:11pm UTC](https://discourse.julialang.org/t/indexing-ordereddict-s-by-index-instead-of-key/77846/4 "2022-03-14T21:11:53Z")

</div>

You’re quite right. I was careful to only add methods for `OrderedDict`s, not normal `Dict`s:

```julia
Base.getindex(h::Base.KeySet{K,<:OrderedDict{K}}, index) where K = h.dict.keys[index]
Base.getindex(h::Base.ValueIterator{<:OrderedDict}, index) = h.dict.vals[index]

```

Assuming the internal layout of `OrderedDict`s always works this way…

Perhaps there’s another dictionary-like data structure which is intended to be `getindex`ed by key _and/or_ linear index, without temporary allocation?
