# How to get first or last n elements from SortedMultiDict?

**URL:** <https://discourse.julialang.org/t/how-to-get-first-or-last-n-elements-from-sortedmultidict/44469>\
**Category:** General Usage\
**Created:** [August 7, 2020, 12:52am UTC](https://discourse.julialang.org/t/how-to-get-first-or-last-n-elements-from-sortedmultidict/44469 "2020-08-07T00:52:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [August 7, 2020, 12:52am UTC](https://discourse.julialang.org/t/how-to-get-first-or-last-n-elements-from-sortedmultidict/44469/1 "2020-08-07T00:52:54Z")

</div>

Let’s say I want to call a function on the first `n` elements of sorted multi-dictionary. I can only come up with this clumsy way of doing it:

```julia
smdict = SortedMultiDict{Float64, Int64}(0.7=>7, 0.1=>1, 0.4=>4, 0.2=>2)
i = startof(smdict)
n = 3

for _ in 1:n
  global i

  println((deref((smdict, i))))
  i = advance((smdict, i))
end

```

Is there a more compact way of iterating through an end interval of `SortedMultiDict`?

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [August 7, 2020, 1:53am UTC](https://discourse.julialang.org/t/how-to-get-first-or-last-n-elements-from-sortedmultidict/44469/2 "2020-08-07T01:53:23Z")

</div>

> [@pauljurczak](#):
>
> `smdict = SortedMultiDict{Float64, Int64}(0.7=>7, 0.1=>1, 0.4=>4, 0.2=>2)`

The following works, as long as you don’t mind using `break`

```julia
julia> smdict = SortedMultiDict{Float64, Int64}(0.7=>7, 0.1=>1, 0.4=>4, 0.2=>2)
SortedMultiDict(Base.Order.ForwardOrdering(),0.1 => 1, 0.2 => 2, 0.4 => 4, 0.7 => 7)

julia> for (count,i) in enumerate(smdict)
         if count > 3
           break
         end
         println(i)
       end
0.1 => 1
0.2 => 2
0.4 => 4

```

If you’d prefer not to use break, then perhaps you can find a more elegant using IterTools.jl.

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [August 7, 2020, 2:07am UTC](https://discourse.julialang.org/t/how-to-get-first-or-last-n-elements-from-sortedmultidict/44469/3 "2020-08-07T02:07:30Z")

</div>

I can’t get the last n elements with this method, once the ordering of `smdict` is defined, right?

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [August 7, 2020, 2:21am UTC](https://discourse.julialang.org/t/how-to-get-first-or-last-n-elements-from-sortedmultidict/44469/4 "2020-08-07T02:21:28Z")

</div>

To iterate backwards through a SortedMultiDict requires invoking lower level primitives like `deref` and `regress`. If you need to do this operation often, then you could make your code cleaner by implementing an `iterate` protocol for stepping backwards through a SortedMultiDict.

In the C++ standard library, wherever an iterator is defined, the language also defines a reverse iterator if it makes sense. As far as I know, nobody has proposed a similar rule for Julia.

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [August 7, 2020, 3:59am UTC](https://discourse.julialang.org/t/how-to-get-first-or-last-n-elements-from-sortedmultidict/44469/5 "2020-08-07T03:59:17Z")

</div>

Stepping forward or backward by one is not the preferable way for me. I would like to be able to do iterator arithmetic and use something like this:

```julia
for (k,v) in inclusive(smdict, startof(smdict), startof(smdict)+n-1)
  println((k, v))
end

```

or

```julia
for (k,v) in inclusive(smdict, endof(smdict)-n+1, endof(smdict))
  println((k, v))
end

```

or even better:

```julia
for (k,v) in inclusive(smdict, 1:n)
  println((k, v))
end

```

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [August 7, 2020, 4:44am UTC](https://discourse.julialang.org/t/how-to-get-first-or-last-n-elements-from-sortedmultidict/44469/6 "2020-08-07T04:44:04Z")

</div>

The current library does not support efficient integer indexing. With a nontrivial amount of additional code, this feature could be supported by adding a field to each internal search-tree node that stores how many descendants it has.

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [August 7, 2020, 4:58am UTC](https://discourse.julialang.org/t/how-to-get-first-or-last-n-elements-from-sortedmultidict/44469/7 "2020-08-07T04:58:29Z")

</div>

In my use case today the efficiency is not an issue. Convenience is more important. I just realized that I can fill an array with tuples, sort it and get n elements from whichever end I need:

```julia
a = [(0.7, 7), (0.1, 1), (0.4, 4), (0.2, 2), (0.1, 1)]
sort!(a)
println(a[1:n])
println(a[end-n+1:end])

```
