[ 'a' ] }, { :name -6ren">
gpt4 book ai didi

Ruby:以树形表示形式转换平面数组

转载 作者:数据小太阳 更新时间:2023-10-29 07:36:33 25 4
gpt4 key购买 nike

我正在尝试编写一个函数,将带有路径信息的平面数组转换为该数组的树表示形式。

目标是像下面这样转动一个数组:

[
{ :name => "a", :path => [ 'a' ] },
{ :name => "b", :path => [ 'a', 'b' ] },
{ :name => "c", :path => [ 'a', 'b', 'c' ] },
{ :name => "d", :path => [ 'a', 'd' ] },
{ :name => "e", :path => [ 'e' ] }
]

变成这样:

[{:node=>{:name=>"a", :path=>["a"]},
:children=>
[{:node=>{:name=>"b", :path=>["a", "b"]},
:children=>
[{:node=>{:name=>"c", :path=>["a", "b", "c"]}, :children=>[]}]},
{:node=>{:name=>"d", :path=>["a", "d"]}, :children=>[]}]},
{:node=>{:name=>"e", :path=>["e"]}, :children=>[]}]

我得到的最接近结果是使用以下代码:

class Tree

def initialize
@root = { :node => nil, :children => [ ] }
end

def from_array( array )
array.inject(self) { |tree, node| tree.add(node) }
@root[:children]
end

def add(node)
recursive_add(@root, node[:path].dup, node)
self
end

private

def recursive_add(parent, path, node)
if(path.empty?)
parent[:node] = node
return
end
current_path = path.shift
children_nodes = parent[:children].find { |child| child[:node][:path].last == current_path }
unless children_nodes
children_nodes = { :node => nil, :children => [ ] }
parent[:children].push children_nodes
end
recursive_add(children_nodes, path, node)
end
end

flat = [
{ :name => "a", :path => [ 'a' ] },
{ :name => "b", :path => [ 'a', 'b' ] },
{ :name => "c", :path => [ 'a', 'b', 'c' ] },
{ :name => "d", :path => [ 'a', 'd' ] },
{ :name => "e", :path => [ 'e' ] }
]

require 'pp'
pp Tree.new.from_array( flat )

但它非常冗长,我觉得它对于非常大的集合可能不是很有效。

在 ruby​​ 中实现该目标的最干净、最有效的方法是什么?

最佳答案

这是我的尝试。

array = [
{ :name => "a", :path => [ 'a' ] },
{ :name => "b", :path => [ 'a', 'b' ] },
{ :name => "c", :path => [ 'a', 'b', 'c' ] },
{ :name => "d", :path => [ 'a', 'd' ] },
{ :name => "e", :path => [ 'e' ] }
]

array
.sort_by{|h| -h[:path].length}
.map{|h| {node: h, children: []}}
.tap{|array|
while array.first[:node][:path].length > 1
child = array.shift
array
.find{|h| h[:node][:name] == child[:node][:path][-2]}[:children]
.push(child)
end
}

# => [
{:node=>{:name=>"e", :path=>["e"]}, :children=>[]},
{:node=>{:name=>"a", :path=>["a"]}, :children=>[
{:node=>{:name=>"d", :path=>["a", "d"]}, :children=>[]},
{:node=>{:name=>"b", :path=>["a", "b"]}, :children=>[
{:node=>{:name=>"c", :path=>["a", "b", "c"]}, :children=>[]}
]}
]}
]

关于Ruby:以树形表示形式转换平面数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13115580/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com