nested hash from array of paths

A

Adam Groves

Hi,

I'm banging my head against the wall with the following problem:

array = ["home", "about", "about/history", "about/company",
"about/history/part1", "about/history/part2"]

I want to build a tree from this array in the form of a nested hash:


{"home" => nil, "about => {"history => ["part1" => nil, "part2" =>
nil]", "company" => nil}}

Any ideas as to how best to solve this?

Regards

Adam
 
A

Adam Shelly

array = ["home", "about", "about/history", "about/company",
"about/history/part1", "about/history/part2"]

I want to build a tree from this array in the form of a nested hash:


{"home" => nil, "about => {"history => ["part1" => nil, "part2" =>
nil]", "company" => nil}}

Any ideas as to how best to solve this?

I could only figure out how to do it using 2 passes:

tree ={}
array.sort.each{|w|
h=tree
w.split('/').each{|part| h=h[part]||=Hash.new}
}

def cleanup h
return true if h.empty?
h.find_all{|k,v|h[k]=nil if v.is_a?(Hash)&&cleanup(v)}
false
end

cleanup tree
p tree
=> {"about"=>{"company"=>nil, "history"=>{"part1"=>nil,
"part2"=>nil}}, "home"=>nil}


-Adam
 
P

Phrogz

Hi,

I'm banging my head against the wall with the following problem:

array = ["home", "about", "about/history", "about/company",
"about/history/part1", "about/history/part2"]

I want to build a tree from this array in the form of a nested hash:

{"home" => nil, "about => {"history => ["part1" => nil, "part2" =>
nil]", "company" => nil}}

Your output doesn't seem consistent. (Why an array sometimes but a
hash others?)
Here's something simple and close:

array = ["home", "about", "about/history", "about/company", "about/
history/part1", "about/history/part2"]

auto_hash = Hash.new{ |h,k| h[k] = Hash.new &h.default_proc }

array.each{ |path|
sub = auto_hash
path.split( "/" ).each{ |dir| sub[dir]; sub = sub[dir] }
}
p auto_hash
#=> {"about"=>{"company"=>{}, "history"=>{"part1"=>{}, "part2"=>{}}},
"home"=>{}}
 
P

Phrogz

array.each{ |path|
  sub = auto_hash
  path.split( "/" ).each{ |dir| sub[dir]; sub = sub[dir] }
}

Bah, of course that can be written as:

array.each{ |path|
sub = auto_hash
path.split( "/" ).each{ |dir| sub = sub[dir] }
}
 
A

Adam Groves

Gavin said:
array.each{ |path|
� sub = auto_hash
� path.split( "/" ).each{ |dir| sub[dir]; sub = sub[dir] }
}

Bah, of course that can be written as:

array.each{ |path|
sub = auto_hash
path.split( "/" ).each{ |dir| sub = sub[dir] }
}

Gavin,

thanks mate - works a charm. I'm glad you spotted my deliberately
inconsistent output as well! ;)

Adam
 
R

Robert Klemme

2008/2/12 said:
array.each{ |path|
sub = auto_hash
path.split( "/" ).each{ |dir| sub[dir]; sub = sub[dir] }
}

Bah, of course that can be written as:

array.each{ |path|
sub = auto_hash
path.split( "/" ).each{ |dir| sub = sub[dir] }
}

Or even

array.each{ |path|
path.to_enum:)split, "/" ).inject(auto_hash){ |sub, dir| sub[dir] }
}

Full credits go to you for this line alone:

auto_hash = Hash.new{ |h,k| h[k] = Hash.new &h.default_proc }

Never occurred to me to use this nice one line approach instead of the
usual two line version (first create block then use it). Thanks a
lot, this is really a gem!

Kind regards

robert
 
P

Phrogz

Full credits go to you for this line alone:

auto_hash = Hash.new{ |h,k| h[k] = Hash.new &h.default_proc }

Never occurred to me to use this nice one line approach instead of the
usual two line version (first create block then use it).  Thanks a
lot, this is really a gem!

I wish I could claim those credits. I had always used the two-line
version two until Jens Wille posted this gem in [ruby-talk:288946]

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/288946
 
R

Robert Klemme

Full credits go to you for this line alone:

auto_hash = Hash.new{ |h,k| h[k] = Hash.new &h.default_proc }

Never occurred to me to use this nice one line approach instead of the
usual two line version (first create block then use it). Thanks a
lot, this is really a gem!

I wish I could claim those credits. I had always used the two-line
version two until Jens Wille posted this gem in [ruby-talk:288946]

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/288946

Ok, then you get at least part of the credits for bringing it up again. ;-)

Kind regards

robert
 
H

Halter, Shari

=20

Registration is now open for Gotham Ruby Conference [GoRuCo] 2008, a
one-day, single-track technical conference, aimed at highly motivated
programmers, in New York City and dedicated to everything Ruby.=20

The conference will be held on=20

Saturday, April 26th at the Manhattan campus of Pace University.

Registration is $125 per person and includes lunch.=20

Based on last year's enthusiastic response, we expect this conference to
sell out, so purchase your tickets early!

Register here:

http://goruco2008.eventwax.com/gotham-ruby-conference-goruco-2008/regist
er
<blocked::http://goruco2008.eventwax.com/gotham-ruby-conference-goruco-2
008/register>=20

=20

GoRuCo 2008 Speakers:

Giles Bowkett=20
Archaeopteryx: A Ruby MIDI Generator

Paul Dix=20
Collective Intelligence: Leveraging User Data to Create Intelligent
Rails Applications

Bryan Helmkamp=20
Story Driven Development: The Next Generation of Rails Functional
Testing

Alex Payne=20
Twitter

Chris Wanstrath=20
Forbidden Fruit: A Taste of Ruby's Parse Tree

Ezra Zygmuntowicz=20
Merb, All you need, None you don't

=20

For more information, visit : http://2008.goruco.com/
<blocked::http://2008.goruco.com/>=20


=20
=20

<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>=0D=0A
The information in this email and any attachments may contain=0D=0A
confidential information that is intended solely for the=0D=0A
attention and use of the named addressee(s). This message or=0D=0A
any part thereof must not be disclosed, copied, distributed=0D=0A
or retained by any person without authorization from the=0D=0A
addressee. If you are not the intended addressee, please=0D=0A
notify the sender immediately, and delete this message.=0D=0A
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>=0D=0A
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top