1   Introduction

This article describes and provides several small tools for processing and operating on the JSON data structures returned by the Jason module to parse a JSON document.

However, since those data structures composed of Elixir maps, lists, numbers, and strings, these functions should be usable on any Elixir data that is composed of nested maps, lists, numbers, and strings.

The source code for module Jason.DataStructures is available here: jason_data_structures.ex.

You can add this module to the ./lib/ directory of a Mix Elixir project.

Then, change directories to your Mix project and do:

$ iex -S mix
iex(68)> recompile

After doing a recompile, while inside IEx, you can get help by typing:

iex> h Jason.DataStructures
iex> h Jason.DataStructures.parsejsondoc
iex> h Jason.DataStructures.iter_map

2   Yaml -- a few notes

For many purposes, JSON and Yaml are interchangable. See this: https://en.wikipedia.org/wiki/YAML#Comparison_with_JSON

There are several packages for working with Yaml in Elixir. For example, yaml-elixir:

Therefore, the tools described in this article will likely be useful to users of Yaml as well as JSON, afterall, the data structures produced by both (maps, lists, as well as numbers and strings) are the same.

The Elixir support for writing out Yaml files does seem a bit thin, but there is yamlix: https://github.com/joekain/yamlix.

Fortunately, there are very simple work-arounds for this. For example, this Python script will read a JSON (or Yaml) file, then write the equivalent Yaml representation to stdout:

import yaml

def convert(path):
    with open(path, 'r') as infile:
        data = yaml.load(infile, yaml.SafeLoader)
        str_data = yaml.dump(data)

And, a somewhat more complete script is here -- json_file_2_yaml_file.py. To use it, you will need to install the Python package PyYAML:

$ pip install pyyaml

And, you can convert in the reverse direction (Yaml to JSON) with this scrpt -- yaml_file_2_json_file.py.

3   A few details

3.1   iter_map

This function will create and return a new JSON tree by performing modifications to nodes in the original tree.

  • map_function -- A function of 1 argument to be applied to Elixir Maps. This function receives a Map as its argument. It should return a Map. see function Jason.DataStructures.demo_map/1 for an example of how to use enum.reduce to do that.
  • list_function -- A function of 1 argument to be applied to Elixir Lists. This function receives a List as its argument. It should return a List. see function Jason.DataStructures.demo_map/1 for an example of how to use Enum.map to do that.
  • string_function -- A function of 1 argument to be applied to strings.
  • number_function -- A function of 1 argument to be applied to numbers.

See functions demo_map01 and demo_map02 for examples of how to call iter_map.

3.2   collect/2

This function returns a list of all nodes in a JSON (or Yaml) data structure (tree) for which a predict function returns true. The predict functions should take one argument (a node in the tree) and should return a boolean (true or false).

3.3   parsejsondoc/1

This convenience function uses the Jason module to parse/decode a JSON document. It returns a tree/map.

3.4   walk/2

This function walks a JSON data structure tree and prints out a bit of mildly interesting information about each node. You could use it as a template for implementing something more interesting and powerful.

3.5   iter_apply/4

This functions walks a JSON tree. It tests each node with the predicate function and , if true, applies the function with arguments to the node.