How to nest a list into a map?

Hey guys!

I have a single list like this:

[x, y, [1], [2] ... w, z, [3], [4] ... ]

My question is how could i recreate a map which assigns the first 2 as nested maps (or as keys) and the lists within the list as values of the nested maps. Such as it could be expressed as

[ key: x [ key: y, value: [1] [2] ] ]
[ key: w [ key: z value: [3] [4] ] ]

Where 1 and 2 belongs to y which belongs to x.
Where 3 and 4 belongs to z which belongs to w.

Does anyone have an idea how to do this in Elixir?

I am more knowledgeable on python dictionaries. So I was thinking on choosing those elements inside the first list that are “not-list” (x, w) an assign them as keys, and those inside a list (1,2) as values.

Hello!

Sorry, I do not fully understand your pseudo code.
Could you express desired input and output using elixir terms?

1 Like

Yes!

[
  "JUZGADO PRIMERO CIVIL DE ENSENADA, B.C. 30 DE JULIO DE 2020",
  "PRIMERA SECRETARIA",
  "Acuerdos",
  ["1", "00268/2016",
   "ROSARIO MEDA MONROY Y OTRAS    VS ANTONIETA GONZALEZ DE CROSTHWAITE TAMBIEN CONOCIDA COMO MARIA ANTONIETA GONZALEZ VIUDA DE CROSTHWAITE ORDINARIO CIVIL PRESCRIPCION POSITIVA"],
  ["2", "00319/2017",
   "SUCESION INTESTAMENTARIA A BIENES DE, GABRIELA ACEVEDO AMADOR. SUCESORIO INTESTAMENTARIO"],
  ["3", "00570/2017",
   "SUCESION TESTAMENTARIA A BIENES DE GUADALUPE RIOS ARRIAGA, TAMBIEN CONOCIDA COMO MARIA GUADALUPE RIOS ARRIAGA    VS REGISTRO PUBLICO DE LA PROPIEDAD Y DE COMERCIO Y OTROS ORDINARIO CIVIL PRESCRIPCION POSITIVA"],
...

I have this single list, that continues alternating between strings and lists. Which I would like to convert such as this:

[
  **key**: "JUZGADO PRIMERO CIVIL DE ENSENADA, B.C. 30 DE JULIO DE 2020",
  **key**: "PRIMERA SECRETARIA" : **key**: " Acuerdos" :  **values** ["1", "00268/2016",
   "ROSARIO MEDA MONROY Y OTRAS    VS ANTONIETA GONZALEZ DE CROSTHWAITE TAMBIEN CONOCIDA COMO MARIA ANTONIETA GONZALEZ VIUDA DE CROSTHWAITE ORDINARIO CIVIL PRESCRIPCION POSITIVA"],
  ["2", "00319/2017",
   "SUCESION INTESTAMENTARIA A BIENES DE, GABRIELA ACEVEDO AMADOR. SUCESORIO INTESTAMENTARIO"] ...

Keep in mind that the initial structure repeats between strings and lists. The former being the values. While the first needs to be taken as keys of the map, and nest them if they are followed by consecutive keys.

TBH I think you’d be better served by parsing the source of that data more carefully; whatever’s producing this list of strings has flattened a lot of the structure out of it:

http://www.pjbc.gob.mx/boletinj/2020/my_html/en200803.htm

I agree. Let me check if I can do this. Any ideas to workaround what I have?
I know in Python we could do dictionaries, I was thinking about doing the same in Elixir with maps.

defmodule Test do
  def data do
    [
      "JUZGADO PRIMERO CIVIL DE ENSENADA, B.C. 30 DE JULIO DE 2020",
      "PRIMERA SECRETARIA",
      "Acuerdos",
      [
        "1",
        "00268/2016",
        "ROSARIO MEDA MONROY Y OTRAS    VS ANTONIETA GONZALEZ DE CROSTHWAITE TAMBIEN CONOCIDA COMO MARIA ANTONIETA GONZALEZ VIUDA DE CROSTHWAITE ORDINARIO CIVIL PRESCRIPCION POSITIVA"
      ],
      ["2", "00319/2017", "SUCESION INTESTAMENTARIA A BIENES DE, GABRIELA ACEVEDO AMADOR. SUCESORIO INTESTAMENTARIO"],
      [
        "3",
        "00570/2017",
        "SUCESION TESTAMENTARIA A BIENES DE GUADALUPE RIOS ARRIAGA, TAMBIEN CONOCIDA COMO MARIA GUADALUPE RIOS ARRIAGA    VS REGISTRO PUBLICO DE LA PROPIEDAD Y DE COMERCIO Y OTROS ORDINARIO CIVIL PRESCRIPCION POSITIVA"
      ],
      "one",
      "two",
      ["1", "date"],
      ["2", "date"]
    ]
  end

  def process(input, acc \\ %{}) do
    {keys, tail} = Enum.split_while(input, &is_binary/1)
    {values, tail} = Enum.split_while(tail, &is_list/1)
    acc = put_in(acc, Enum.map(keys, &Access.key(&1, %{})), values)

    case tail do
      [] -> acc
      _ -> process(tail, acc)
    end
  end
end

and output

> Test.process(Test.data())
%{
  "JUZGADO PRIMERO CIVIL DE ENSENADA, B.C. 30 DE JULIO DE 2020" => %{
    "PRIMERA SECRETARIA" => %{
      "Acuerdos" => [
        ["1", "00268/2016",
         "ROSARIO MEDA MONROY Y OTRAS    VS ANTONIETA GONZALEZ DE CROSTHWAITE TAMBIEN CONOCIDA COMO MARIA ANTONIETA GONZALEZ VIUDA DE CROSTHWAITE ORDINARIO CIVIL PRESCRIPCION POSITIVA"],
        ["2", "00319/2017",
         "SUCESION INTESTAMENTARIA A BIENES DE, GABRIELA ACEVEDO AMADOR. SUCESORIO INTESTAMENTARIO"],
        ["3", "00570/2017",
         "SUCESION TESTAMENTARIA A BIENES DE GUADALUPE RIOS ARRIAGA, TAMBIEN CONOCIDA COMO MARIA GUADALUPE RIOS ARRIAGA    VS REGISTRO PUBLICO DE LA PROPIEDAD Y DE COMERCIO Y OTROS ORDINARIO CIVIL PRESCRIPCION POSITIVA"]
      ]
    }
  },
  "one" => %{"two" => [["1", "date"], ["2", "date"]]}
}

Is this a structure you are looking for?

2 Likes

Precisely! Amazing, thank you. Let me check and I’ll get back to you.

Any idea how to avoid the json being modified alphabetically?

Which JSON?

If you are talking about JSON objects, their keys have no order.

Instead of this :

%{
  "JUZGADO PRIMERO CIVIL DE ENSENADA, B.C. 30 DE JULIO DE 2020" => %{
    "PRIMERA SECRETARIA" => %{
      "Acuerdos" => [
        ["1", "00268/2016",
         "ROSARIO MEDA MONROY Y OTRAS    VS ANTONIETA GONZALEZ DE CROSTHWAITE TAMBIEN CONOCIDA COMO MARIA ANTONIETA GONZALEZ VIUDA DE CROSTHWAITE ORDINARIO CIVIL PRESCRIPCION POSITIVA"],
        ["2", "00319/2017",
         "SUCESION INTESTAMENTARIA A BIENES DE, GABRIELA ACEVEDO AMADOR. SUCESORIO INTESTAMENTARIO"],
        ["3", "00570/2017",
         "SUCESION TESTAMENTARIA A BIENES DE GUADALUPE RIOS ARRIAGA, TAMBIEN CONOCIDA COMO MARIA GUADALUPE RIOS ARRIAGA    VS REGISTRO PUBLICO DE LA PROPIEDAD Y DE COMERCIO Y OTROS ORDINARIO CIVIL PRESCRIPCION POSITIVA"]
      ]
    }
  },

But after expanding the usability of the code it begins to map my “keys” on alphabetical order. Sorry for the basic questions, I am still learning Elixir.

That’s not JSON, that’s an elixir map.

It doesn’t imply any ordering of keys as well.

For small maps it might sometimes look like the keys are in order of insertion, but this is due to an implementation detail.

It is better to not assume any order in maps.

2 Likes