Reputation: 4634
I have no clue to solve this question. I got a nested
hash
inside an array
called data
. Here is its structure.
data =
[
{
:id => 1,
:name => "S1",
:children => [
{
:id => 10,
:name => "S10",
:children => [
{
:id => 20,
:name => "S20"
}
]
}
]
},
{
:id => 1,
:name => "S1",
:children => [
{
:id => 10,
:name => "S10",
:children => [
{
:id => 21,
:name => "S21"
}
]
}
]
},
{
:id => 1,
:name => "S1",
:children => [
{
:id => 11,
:name => "S11",
:children => [
{
:id => 22,
:name => "S22"
}
]
}
]
}
]
As you can see, there are bunch of elements which have the same id
in the first layer or second layer, so I need to group them.
I hope the result will be
result=
[
{
:id => 1,
:name => "S1",
:children => [
{
:id => 10,
:name => "S10",
:children => [
{
:id => 20,
:name => "S20"
},
{
:id => 21,
:name => "S21"
}
]
},
{
:id => 11,
:name => "S11",
:children => [
{
:id => 22,
:name => "S22"
}
]
}
]
}
]
I've tried somthing like
data.group_by{|s| s[:id]}
However, it would only group the first layer, I don't know how to group nested structure.
Upvotes: 2
Views: 1185
Reputation: 3501
Yeah you need some kind of recursive method to recursively combine and group the nested children.
This produces the result you want:
def group(data)
r = {}
# Combine the children
data.each do |d|
if r[d[:id]]
r[d[:id]][:children] += d[:children]
else
r[d[:id]] = d
end
end
# Now group the children
r.values.map do |d|
d[:children] = group(d[:children]) if d[:children]
d
end
end
Upvotes: 4