nested hash from array of paths

Discussion in 'Ruby' started by Adam Groves, Feb 11, 2008.

  1. Adam Groves

    Adam Groves Guest

    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
    --
    Posted via http://www.ruby-forum.com/.
     
    Adam Groves, Feb 11, 2008
    #1
    1. Advertising

  2. Adam Groves

    Adam Shelly Guest

    On 2/11/08, Adam Groves <> wrote:
    > 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
     
    Adam Shelly, Feb 12, 2008
    #2
    1. Advertising

  3. Adam Groves

    Phrogz Guest

    On Feb 11, 4:43 pm, Adam Groves <> wrote:
    > 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"=>{}}
     
    Phrogz, Feb 12, 2008
    #3
  4. Adam Groves

    Phrogz Guest

    On Feb 11, 10:00 pm, Phrogz <> wrote:
    > 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] }
    }
     
    Phrogz, Feb 12, 2008
    #4
  5. Adam Groves

    Adam Groves Guest

    Gavin Kistner wrote:
    > On Feb 11, 10:00�pm, Phrogz <> wrote:
    >> 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
    --
    Posted via http://www.ruby-forum.com/.
     
    Adam Groves, Feb 12, 2008
    #5
  6. 2008/2/12, Phrogz <>:
    > On Feb 11, 10:00 pm, Phrogz <> wrote:
    > > 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

    --
    use.inject do |as, often| as.you_can - without end
     
    Robert Klemme, Feb 12, 2008
    #6
  7. Adam Groves

    Phrogz Guest

    On Feb 12, 7:12 am, Robert Klemme <> wrote:
    > 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
     
    Phrogz, Feb 12, 2008
    #7
  8. On 12.02.2008 15:30, Phrogz wrote:
    > On Feb 12, 7:12 am, Robert Klemme <> wrote:
    >> 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
     
    Robert Klemme, Feb 12, 2008
    #8
  9. -Registration Open for GoRuCo 2008-

    =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
     
    Halter, Shari, Feb 13, 2008
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Noah
    Replies:
    5
    Views:
    786
  2. rp
    Replies:
    1
    Views:
    534
    red floyd
    Nov 10, 2011
  3. Ohad Lutzky

    Paths, gentleman, paths

    Ohad Lutzky, Nov 6, 2006, in forum: Ruby
    Replies:
    2
    Views:
    197
    David Vallner
    Nov 7, 2006
  4. Anthony Martinez
    Replies:
    4
    Views:
    274
    Robert Klemme
    Jun 11, 2007
  5. Srijayanth Sridhar
    Replies:
    19
    Views:
    624
    David A. Black
    Jul 2, 2008
Loading...

Share This Page