Turn array into array of hashes (Ruby)

Viewed 56

I'm struggling on a task that consists of turning an array into an array of hashes with children.

Basically, I need to create a hierarchical html table of content from an array of headings.

Here is the initial array:

- !ruby/object:Prismic::Fragments::StructuredText::Block::Heading
  text: Quelles espèces de dauphins peut-on voir en Martinique ?
  level: 2
- !ruby/object:Prismic::Fragments::StructuredText::Block::Heading
  text: Dauphin de Fraser
  level: 3
- !ruby/object:Prismic::Fragments::StructuredText::Block::Heading
  text: Dauphin tacheté pantropical
  level: 3
- !ruby/object:Prismic::Fragments::StructuredText::Block::Heading
  text: Dauphin d’Électre
  level: 3
- !ruby/object:Prismic::Fragments::StructuredText::Block::Heading
  text: Le grand dauphin
  level: 3
- !ruby/object:Prismic::Fragments::StructuredText::Block::Heading
  text: Globicéphale tropical
  level: 3
- !ruby/object:Prismic::Fragments::StructuredText::Block::Heading
  text: Les meilleurs spots pour voir les dauphins en Martinique
  level: 2
- !ruby/object:Prismic::Fragments::StructuredText::Block::Heading
  text: Conditions idéales pour l’observation des dauphins en Martinique
  level: 2
- !ruby/object:Prismic::Fragments::StructuredText::Block::Heading
  text: Comment se déroule cette balade en mer ?
  level: 2

Basically, I need the previous array to look like this array of hashes :

[
  {
    "text" => "Quelles espèces de dauphins peut-on voir en Martinique ?",
    "level" => 2,
    "children" => [
      {
        "text" => "Dauphin de Fraser",
        "level" => 3,
        "children" => []
      },
      {
        "text" => "Dauphin tacheté pantropical",
        "level" => 3,
        "children" => []
      },
      {
        "text" => "Dauphin d’Électre",
        "level" => 3,
        "children" => []
      },
      {
        "text" => "Le grand dauphin",
        "level" => 3,
        "children" => []
      },
      {
        "text" => "Globicéphale tropical",
        "level" => 3,
        "children" => []
      }
    ]
  },
  {
    "text" => "Les meilleurs spots pour voir les dauphins en Martinique",
    "level" => 2,
    "children" => []
  },
  {
    "text" => "Conditions idéales pour l’observation des dauphins en Martinique",
    "level" => 2,
    "children" => []
  },
  {
    "text" => "Comment se déroule cette balade en mer ?",
    "level" => 2,
    "children" => []
  }
]

So, an item needs to be included in the previous item if its level value is greater than the previous item. Allowing it to create a hierarchical array of hashes.

Any help on that ? Thanks in advance !

1 Answers

Ruby's inject method should solve your problem:

array.inject([]) do |ar,item|
  collection = case item.level
               when 2
                 ar
               when 3
                 ar[-1][:children]
               when 4
                 ar[-1][:children][-1][:children]
               when 5
                 ar[-1][:children][-1][:children][-1][:children]
               # etc..
               end

    collection.push {text: item.text,
                     level: item.level,
                     children: []}
  
  ar
end

where is array is the array of ruby objects you listed in your post.

Related