I have a list of files sorted in an array, like:
arr = ["./a.txt", "./b.txt", "./bar/z.php", "./foo/hello/y.php", "./foo/x.php"]
How to create a dynatree object out of this? A dynatree object for it, should look like:
[{"name"=>".", "title" => ".", "isDir" => true, "children" =>
[{"name"=>"a.txt", "title" => "a.txt"},
{"name"=>"b.txt", "title" => "b.txt"},
{"name" => "bar", "title"=>"bar", "isDir"=>true, "children" =>
[{"name" => "z.php", "title" => "z.php"},
{"name" => "foo", "title" => "foo", "isDir" => true, "children" =>
[{"name" => "x.php", "title" => "x.php"},
{ "name" => "hello", "title" => "hello", "children" =>
[{"name" => "y.php", "title"=>"y.php"}
]
}
]
}
]
}
]
}]
PS: This question might seem a lazy post, but I have spent more than 20 hrs now solving this. So any help will be greatly appreciated. Thanks.
My idea is to iterate over each paths. Each path is split by /
into parts. The last part is the file, others - directories.
I go through each part adding new directories unless they were already added. In the end of each iteration I switch the context to the next level - children
array of the last directory.
File is the last part - I simple append it to the current context.
arr = ["./a.txt", "./b.txt", "./bar/z.php", "./foo/hello/y.php", "./foo/x.php"]
tree = []
arr.each do |path|
# start at the beginning on each iteration
current_level = tree
# split path by '/'
splitted_path = path.split('/')
# remember the size of parts in path to distinct files from folders
size = splitted_path.size
# iterate over each part of a path
splitted_path.each_with_index do |node, i|
if i != size - 1
# current node is path
# detect if it is already in the array
unless current_level.detect { |n| n['name'] == node }
# if not - append it to array
current_level << {
'name' => node,
'title' => node,
'isDir' => true,
'children' => []
}
end
# set the current level to the new node's children array
current_level = current_level.detect { |n| n['name'] == node }['children']
else
# node is a file - append it to the children array on current level
current_level << {
'name' => node,
'title' => node
}
end
end
end
tree