Chapter 19: Dictionaries and JSON Files

Return to all notes

A dictionary or associative array in Julia is a bit like a dictionary that sits on your bookcase–yes the one that you use to look up words. It is an array that is indexed by a string, like a definition is indexed by the word. For example,

dict=Dict("A"=>1,"B"=>7,"C"=>-7)

The value can be looked up by

dict["A"]

which returns 1. A couple of helpful functions on dictionary are values which returns all of the values of a dictionary and keys, all of the indexes (or keys) of the dictionary.

For example,

collect(values(dict))

returns the array [7,1,-7] and

collect(keys(dict))

returns the array ["B","A","C"] and notice in both cases, the order changed from the way it was put in.

Complex Dictionaries

The above was a simple dictionary, however, Dictionaries can be a mixture of various data types. As seen above, a dictionary has keys and values, and are typically of either Ints, Chars or Strings, where String are the most common as shown above.

The values of a Dictionary can vary and don’t need to be the same type with a dictionary. For example:

dict2 = Dict("A"=>1, "B"=>"Hello", "C"=> 1.23)

and when Julia returns:

Dict{String,Any} with 3 entries:
  "B" => "Hello"
  "A" => 1
  "C" => 1.23

then notice that it doesn’t keep the order of the pairs, mainly because the order doesn’t matter for a Dictionary. This has key type String and value type Any. And Dictionaries can nest:

dict3 = Dict(1=> "Hello", 3 => [1,2,3,4,5], 5 => Dict("homer"=> 2.34,"marge"=>3.19))

which returns:

Dict{Int64,Any} with 3 entries:
  3 => [1, 2, 3, 4, 5]
  5 => Dict("homer"=>2.34,"marge"=>3.19)
  1 => "Hello"

which shows that the key is an Int64 and then the values are Any and you can see that again the keys are not in the same order as entered.

JSON files

There are many different types of files that are used to transfer data. A very common one is a JSON which stands for JavaScript Object Notation, which is a way to store data associated with javascript an webpages. An example (from the wikipedia page) is

{
  "firstName": "John",
  "lastName": "Smith",
  "age": 25,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021"
  },
  "phoneNumber": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "fax",
      "number": "646 555-4567"
    }
  ],
  "gender": {
    "type": "male"
  }
}

where many of these are field/value pairs, but also arrays are valid.

Generally, the use of these is importing or exporting an object in JSON. For example, the above can be written as a Julia string:

str = "{
  \"firstName\": \"John\",
  \"lastName\": \"Smith\",
  \"age\": 25,
  \"address\": {
    \"streetAddress\": \"21 2nd Street\",
    \"city\": \"New York\",
    \"state\": \"NY\",
    \"postalCode\": \"10021\"
  },
  \"phoneNumber\": [
    {
      \"type\": \"home\",
      \"number\": \"212 555-1234\"
    },
    {
      \"type\": \"fax\",
      \"number\": \"646 555-4567\"
    }
  ],
  \"gender\": {
    \"type\": \"male\"
  }
}"

and to load this, we need to (maybe you’ll need add the JSON package and then) load the package:

using JSON

and parsing the JSON:

info = JSON.parse(str)

returns

Dict{String,Any} with 6 entries:
  "gender"      => Dict{String,Any}(Pair{String,Any}("type","male"))
  "phoneNumber" => Any[Dict{String,Any}(Pair{String,Any}("number","212 555-1234…
  "lastName"    => "Smith"
  "firstName"   => "John"
  "age"         => 25
  "address"     => Dict{String,Any}(Pair{String,Any}("streetAddress","21 2nd St…

which is a Dictionary. (Note that the keys are type String but since the values have a mixed type, the type is listed as Any). For example, we can echo the first and last name with:

string(info["firstName"]," ",info["lastName"])

and we can echo the fax number as

info["phoneNumber"][2]["number"]

since it is the “number” of the 2nd “phoneNumber”.

writing out/exporting a Dictionary

Let’s say we have a restaurant menu stored as the following dictionary:

menu=Dict("pancakes"=>Dict("type"=>"Breakfast","cost"=>7.00,"options"=>["Chocolate Chip","Buckwheat"]),
"hamburger"=>Dict("type"=>["Lunch","Dinner"],"cost"=>9.00,"options"=>["Cheddar","Mushrooms","Bacon"]),
"onion soup"=>Dict("type"=>["Lunch","Dinner"],"cost"=>5.00))

A good way to store it would be to export it as a JSON format. typing

JSON.json(menu)

returns

"{\"hamburger\":{\"options\":[\"Cheddar\",\"Mushrooms\",\"Bacon\"],\"cost\":9.0,\"onion soup\":{\"cost\":5.0,\"type\":[\"Lunch\",\"Dinner\"]},\"type\":[\"Lunch\",\"Dinner\"]},\"pancakes\":{\"options\":[\"Chocolate Chip\",\"Buckwheat\"],\"cost\":7.0,\"type\":\"Breakfast\"}}"

It can also be easily written to a file with the following:

f = open("menu.json","w")
JSON.print(f,menu)
close(f)

and then look at the file “menu.json” in the same directory as where your julia document is.

Parsing a JSON file.

Let’s say that we have a more extensive menu in the JSON file menu2.json.

To load this file and parse it, JSON has everything wrapped together:

menu2=JSON.parsefile("menus2.json")

Exercise

Find the sum of the costs of all of the menu items using the dictionary.