Reputation: 45
I'm trying to rearrange data in array to be in hash format but I pretty messed up using nested if
Sample Data
[
["England", "London", "University College London ", "Faculty of Law"],
["England", "London", "University College London ", "Faculty of Engineering"],
["England", "London", "Imperial College London", "Faculty of Medicine"],
["England", "Manchester", "University of Manchester", "Faculty of Engineering"]
]
Expected Output
{:name=>"England",
:level=>1,
:children=>[{:name=>"London",
:level=>2,
:children=>[{:name=>"University College London ",
:level=>3,
:children=>[{:name=>"Faculty of Law",
:level=>4,
:children=>[]},
{:name=>"Faculty of Engineering",
:level=>4, :children=>[]}]},
{:name=>"Imperial College London",
:level=>3,
:children=>[{:name=>"Faculty of Engineering",
:level=>4,
:children=>[]}]
}]
}]
}
hope I have provide clear explaination
ps. edit to show what I've tried first i make array of hash then do something like this I thought it wouldn't be confused this much
result = []
arr.each do |b|
if result.any? {|r| r[:name] == b[:name]}
if result.first[:children].any? {|r| r[:name] == b[:children].first[:name]}
if result.first[:children].any?{|c| c[:children].any? {|r| r[:name] == b[:children].first[:children].first[:name] && c[:name] == b[:children].first[:name] }}
if result.first[:children].any? {|r| r[:children].any? {|c| c[:children].any?{|k| k[:name] == b[:children].first[:children].first[:children].first[:name] && (c[:name] == b[:children].first[:children].first)}}}
else
result.first[:children].any?{|c| c[:children].any? {|r| r[:name] == b[:children].first[:children].first[:name] ; r[:children] << b[:children].first[:children].first[:children].first}}
end #fourth
else
result.first[:children].any? {|r| r[:name] == b[:children].first[:name]; r[:children] << b[:children].first[:children].first}
end
else
result.any? {|r| r[:name] == b[:name] ; r[:children] << b[:children].first}
end
else result << b
end
end
Upvotes: 3
Views: 647
Reputation: 1517
You could do this recursive like this:
def map_objects(array, level = 1)
new_obj = []
array.group_by(&:shift).each do |key, val|
new_obj << {:name=>key, :level=>level, :children=>map_objects(val, level + 1)} if key
end
new_obj
end
For your array it will return like this:
# [
# {:name => "England", :level => 1, :children => [
# {:name => "London", :level => 2, :children => [
# {:name => "University College London ", :level => 3, :children => [
# {:name => "Faculty of Law", :level => 4, :children => []
# },
# {:name => "Faculty of Engineering", :level => 4, :children => []
# }]
# },
# {:name => "Imperial College London", :level => 3, :children => [
# {:name => "Faculty of Medicine", :level => 4, :children => []
# }]
# }]
# },
# {:name => "Manchester", :level => 2, :children => [
# {:name => "University of Manchester", :level => 3, :children => [
# {:name => "Faculty of Engineering", :level => 4, :children => []
# }]
# }]
# }]
# }
# ]
Upvotes: 2
Reputation: 292
I hope the following code can help you:
input = [
["England", "London", "University College London ", "Faculty of Law"],
["England", "London", "University College London ", "Faculty of Engineering"],
["England", "London", "Imperial College London", "Faculty of Medicine"],
["England", "Manchester", "University of Manchester", "Faculty of Engineering"]
]
output = Array.new
input.each do |i|
if output.select { |out| out[:name] == i[0] }.empty?
output << { :name => i[0], :level => 1, :child => [] }
end
level1 = output.select { |out| out[:name] == i[0] }
level1.each do |l1|
if l1[:child].select { |l| l[:name] == i[1] }.empty?
l1[:child] << { :name => i[1], :level => 2, :child => [] }
end
end
level1.each do |l1|
level2 = l1[:child].select { |l| l[:name] == i[1] }
level2.each do |l2|
if l2[:child].select { |l| l[:name] == i[2] }.empty?
l2[:child] << { :name => i[2], :level => 3, :child => [] }
end
end
end
level1.each do |l1|
level2 = l1[:child].select { |l| l[:name] == i[1] }
level2.each do |l2|
level3 = l2[:child].select { |l| l[:name] == i[2] }
level3.each do |l3|
if l3[:child].select { |l| l[:name] == i[3] }.empty?
l3[:child] << { :name => i[3], :level => 4 }
end
end
end
end
end
puts output
Upvotes: 0