# Reorder dictionary keys

**URL:** <https://discourse.julialang.org/t/reorder-dictionary-keys/111547>\
**Category:** Performance\
**Tags:** dictionary\
**Created:** [March 13, 2024, 1:09am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547 "2024-03-13T01:09:45Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sandy45](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@Sandy45](https://discourse.julialang.org/u/Sandy45)\
**Post date:** [March 13, 2024, 1:09am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547/1 "2024-03-13T01:09:45Z")

</div>

I have dictionary in below format and would like to check if we have any existing methos that can reorder dictionary if we provide the array with the key names in desired order?

I would like to see my final dictionary in below order of key along with their values.

desired\_order = [“date”, “time”, “field2”, “field1”, “field3”, “field4”, “field5”, “field6”, “field7”]

```julia
[Dict{String, Any}("field1" => 26, "field2" => 1, "time" => "14:00", "field3" => 0, "date" => "2024-03-09", "field4" => 102, "field5" => 17, "field6" => 10, "field7" => 97), Dict{String, Any}("field1" => 1, "field2" => 1, "time" => "04:00", "field3" => 0, "date" => "2024-03-09", "field4" => 6, "field5" => 0, "field6" => 2, "field7" => 5), Dict{String, Any}("field1" => 18, "field2" => 1, "time" => "17:45", "field3" => 7, "date" => "2024-03-07", "field4" => 101, "field5" => 9, "field6" => 10, "field7" => 114), Dict{String, Any}("field1" => 0, "field2" => 0, "time" => "06:00", "field3" => 0, "date" => "2024-03-10", "field4" => 26, "field5" => 5, "field6" => 5, "field7" => 46)]

```

---

<div class="post-metadata">

**Author:** ![screw\_dog](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/screw_dog/32/48119_2.png) [@screw\_dog](https://discourse.julialang.org/u/screw_dog)\
**Post date:** [March 13, 2024, 1:24am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547/2 "2024-03-13T01:24:44Z")

</div>

Dictionaries are inherently unordered. If you want to order the contents you’ll need to convert it into a different form, the most obvious is a vector of pairs.

```julia
pair_vec = [dict...]

```

This vector can then be sorted. To sort in the order we want we can say that for two pairs, `x` and `y`, `x` comes first if its key is before `y`’s key in `desired_order`. We put this in a function:

```julia
islessthan(x, y) = findfirst((==)(first(x)), desired_order) <= findfirst((==)(first(y)), desired_order)

```

Note here `x`, `y` are pairs, so `first(x)` is equivalent to the key of `x`.

`(==)(val)` is the same as `s -> s == val`. That is, it’s a function that returns true if its argument is the same as `val`.

Lastly, `findfirst(fn, desired_order)` returns the index of the first element of `desired_order` where `fn` is true. In our example, it’s the index of the element of `desired_order` that equals the key of `x`.

Then to sort in our desired order use:

```julia
sort(pair_vec; lt=islessthan)

```

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [March 13, 2024, 1:46am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547/3 "2024-03-13T01:46:21Z")

</div>

> [@Sandy45](#):
>
> I have dictionary in below format and would like to check if we have any existing methos that can reorder dictionary if we provide the array with the key names in desired order?

For ordered dictionaries, there’s [OrderedDict](https://juliacollections.github.io/OrderedCollections.jl/latest/ordered_containers.html), this will provide exactly what you want.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [March 13, 2024, 1:47am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547/4 "2024-03-13T01:47:13Z")

</div>

There are also an OrderedDict data structure which would do the job:

```julia
using DataStructures

desired_order = ["date", "time", "field2", "field1", "field3", "field4", "field5", "field6", "field7"]

data = [Dict{String, Any}("field1" => 26, "field2" => 1, "time" => "14:00", "field3" => 0, "date" => "2024-03-09", "field4" => 102, "field5" => 17, "field6" => 10, "field7" => 97), Dict{String, Any}("field1" => 1, "field2" => 1, "time" => "04:00", "field3" => 0, "date" => "2024-03-09", "field4" => 6, "field5" => 0, "field6" => 2, "field7" => 5), Dict{String, Any}("field1" => 18, "field2" => 1, "time" => "17:45", "field3" => 7, "date" => "2024-03-07", "field4" => 101, "field5" => 9, "field6" => 10, "field7" => 114), Dict{String, Any}("field1" => 0, "field2" => 0, "time" => "06:00", "field3" => 0, "date" => "2024-03-10", "field4" => 26, "field5" => 5, "field6" => 5, "field7" => 46)]

od_data = [OrderedDict(k=>d[k] for k in desired_order) for d in data]

```

Now `od_data` containts the rightly ordered Dicts:

```julia
julia> od_data[1]
OrderedDict{String, Any} with 9 entries:
  "date" => "2024-03-09"
  "time" => "14:00"
  "field2" => 1
  "field1" => 26
  "field3" => 0
  "field4" => 102
  "field5" => 17
  "field6" => 10
  "field7" => 97

```

---

<div class="post-metadata">

**Author:** ![Sandy45](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@Sandy45](https://discourse.julialang.org/u/Sandy45)\
**Post date:** [March 13, 2024, 2:39am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547/5 "2024-03-13T02:39:07Z")

</div>

@Dan This works perfect but I have one more issue here, the data may not have all the keys that specified in the desired\_order array, so can we implement haskey logic within your solution above?

---

<div class="post-metadata">

**Author:** ![Sandy45](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@Sandy45](https://discourse.julialang.org/u/Sandy45)\
**Post date:** [March 13, 2024, 2:40am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547/6 "2024-03-13T02:40:24Z")

</div>

@Dan Nvm, I was able to write the logic. Thanks!

---

<div class="post-metadata">

**Author:** ![Sandy45](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@Sandy45](https://discourse.julialang.org/u/Sandy45)\
**Post date:** [March 13, 2024, 2:51am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547/7 "2024-03-13T02:51:22Z")

</div>

@Dan I am adding one more pair of values to this dict say od\_data[“work\_data”] and assigning the values using same logic above and the order is getting shuffled if I do this, Any thoughts? may be we need to create separate dict and merge both instead of directly assigning.?

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [March 13, 2024, 3:05am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547/8 "2024-03-13T03:05:57Z")

</div>

The order of the keys is the same as the insertion order (unless the keys are reordered). Therefore, to get key `a` before key `b`, `a` needs to be inserted first. I suppose that dummy entries can be inserted as placeholders for future values if the key order requires it. When updating the value of a key, it does not move in the order.

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [March 13, 2024, 6:58am UTC](https://discourse.julialang.org/t/reorder-dictionary-keys/111547/9 "2024-03-13T06:58:43Z")

</div>

It is worth mentioning [Dictionaries.jl](https://github.com/andyferris/Dictionaries.jl) as well, which provides an alternative implementation of dictionaries which are ordered by default.
