ruby 21 lines · 5 steps

Building a tree from flat rows in Ruby

Group flat rows by parent id once, then recurse to assemble a nested tree in a single pass.

Explained by highlit
1def build_tree(rows, root_id: nil)
2 children_by_parent = Hash.new { |hash, key| hash[key] = [] }
3 
4 rows.each do |row|
5 children_by_parent[row[:parent_id]] << row
6 end
7 
8 attach = lambda do |parent_id|
9 children_by_parent[parent_id]
10 .sort_by { |row| [row[:position] || 0, row[:id]] }
11 .map do |row|
12 {
13 id: row[:id],
14 name: row[:name],
15 children: attach.call(row[:id])
16 }
17 end
18 end
19 
20 attach.call(root_id)
21end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Bucketing rows by parent id up front turns tree-building into O(n) instead of repeated scans.
  2. 2A default block on Hash lets you append to keys without pre-initializing every bucket.
  3. 3A named lambda can call itself recursively because it closes over its own local variable.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Building a tree from flat rows in Ruby — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code