1

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 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Okay this looks about right, thanks ! One thing, there can be more that 2 and 3 levels... It can be 4, 5 and 6 as well. How should I handle that ? I guess I have to modify if item.level == 2...
edited my answer... does that do what you need?
There is certainly a way to do this without hard coding numbers
You should be able to replace that whole case statement with this: collection = ar; (item.level - 2).times { collection = collection[-1][:children] }
@maxpleaner you are a literal god. No idea how this works but it works. I should dig in it a little later. Thanks a lot (wo)man !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.