Ruby dup/clone recursively

前端 未结 5 1643
猫巷女王i
猫巷女王i 2020-12-10 01:30

I have a hash like:

h = {\'name\' => \'sayuj\', 
     \'age\' => 22, 
     \'project\' => {\'project_name\' => \'abc\', 
                   \'dur         


        
相关标签:
5条回答
  • 2020-12-10 01:37

    Here's how you make deep copies in Ruby

    d = Marshal.load( Marshal.dump(h) )
    
    0 讨论(0)
  • 2020-12-10 01:37

    This is an answer to a reasonably old question, but I happened upon it while implementing something similar, thought I'd chime in for a more efficient method.

    For the simple, two level deep hash like above, you can also do something like this:

    d = h.inject({}) {|copy, (key, value)| 
        copy[key] = value.dup rescue value; copy
    }
    

    I ran a test on a hash of hashes with 4k elements, each a few hundred bytes, and it was about 50% faster than the Marshal.dump/load

    Of course, it's not as complete, as it won't work if you have a hash as, e.g., the value of the 'project_name' field, but for a simple 2 level hash, it works great / faster.

    0 讨论(0)
  • 2020-12-10 01:38

    If you are in Rails: Hash.deep_dup

    0 讨论(0)
  • 2020-12-10 01:52

    Another alternative is to use the full_dup gem (full disclosure: I am the author of that gem) that handles arrays, hashes, structs, and is extendable to user defined classes.

    To use:

    require 'full_dup'
    # Other code omitted ...
    d = h.full_dup
    

    Also note that full_dup handles complex data relationships including those with loops or recursion.

    0 讨论(0)
  • 2020-12-10 01:56

    In case the Marchal #dump/load pair isn't work, for rails there is a Hash's method #deep_dup, so you can:

    h = {'name' => 'sayuj', 
     'age' => 22, 
     'project' => {'project_name' => 'abc', 
                   'duration' => 'prq'}}
    
    h1 = h.deep_dup
    
    0 讨论(0)
提交回复
热议问题