zoukankan      html  css  js  c++  java
  • [转] Hash#deep_merge

    1 # Hash#deep_merge
    2 # From: http://pastie.textmate.org/pastes/30372, Elliott Hird
    3 # Source: http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
    4 # This file contains extensions to Ruby and other useful snippits of code.
    5 # Time to extend Hash with some recursive merging magic.
    6  
    7
    8 class Hash
    9
    10 # Merges self with another hash, recursively.
    11 #
    12 # This code was lovingly stolen from some random gem:
    13 # http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
    14 #
    15 # Thanks to whoever made it.
    16
    17 def deep_merge(hash)
    18 target = dup
    19
    20 hash.keys.each do |key|
    21 if hash[key].is_a? Hash and self[key].is_a? Hash
    22 target[key] = target[key].deep_merge(hash[key])
    23 next
    24 end
    25
    26 target[key] = hash[key]
    27 end
    28
    29 target
    30 end
    31
    32
    33 # From: http://www.gemtacular.com/gemdocs/cerberus-0.2.2/doc/classes/Hash.html
    34 # File lib/cerberus/utils.rb, line 42
    35
    36 def deep_merge!(second)
    37 second.each_pair do |k,v|
    38 if self[k].is_a?(Hash) and second[k].is_a?(Hash)
    39 self[k].deep_merge!(second[k])
    40 else
    41 self[k] = second[k]
    42 end
    43 end
    44 end
    45
    46
    47 #-----------------
    48
    49 # cf. http://subtech.g.hatena.ne.jp/cho45/20061122
    50 def deep_merge2(other)
    51 deep_proc = Proc.new { |k, s, o|
    52 if s.kind_of?(Hash) && o.kind_of?(Hash)
    53 next s.merge(o, &deep_proc)
    54 end
    55 next o
    56 }
    57 merge(other, &deep_proc)
    58 end
    59
    60
    61 def deep_merge3(second)
    62
    63 # From: http://www.ruby-forum.com/topic/142809
    64 # Author: Stefan Rusterholz
    65
    66 merger = proc { |key,v1,v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
    67 self.merge(second, &merger)
    68
    69 end
    70
    71
    72 def keep_merge(hash)
    73 target = dup
    74 hash.keys.each do |key|
    75 if hash[key].is_a? Hash and self[key].is_a? Hash
    76 target[key] = target[key].keep_merge(hash[key])
    77 next
    78 end
    79 #target[key] = hash[key]
    80 target.update(hash) { |key, *values| values.flatten.uniq }
    81 end
    82 target
    83 end
    84
    85 end
    86
    87
    88 h = {:a => {:b => :c}}.merge({:a => {:l => :x}})
    89 p h #=> {:a=>{:l=>:x}}
    90
    91 h = {:a => {:b => :c}}.deep_merge({:a => {:l => :x}})
    92 p h #=> {:a=>{:b=>:c, :l=>:x}}
    93 puts
    94
    95
    96 h1 = {:a => {:b => :c}}
    97 h2 = {:a => {:l => :x}}
    98
    99 h = h1.deep_merge(h2)
    100 p h1, h2, h
    101 puts
    102
    103 h = h1.deep_merge2(h2)
    104 p h1, h2, h
    105 puts
    106
    107 h = h1.deep_merge!(h2)
    108 p h1, h2, h
    109
    110
    111 h1 = {:a => {:b => :c}}
    112 h2 = {:a => {:l => :x}}
    113
    114 p h1.deep_merge3(h2)
    115 p h1, h2
    116
    117
    118 first = {
    119 :data=>{
    120 :name=>{
    121 :first=>'Sam',
    122 :middle=>'I',
    123 :last=>'am'
    124 }
    125 }
    126 }
    127
    128 second={
    129 :data=>{
    130 :name=>{
    131 :middle=>'you',
    132 :last=>'are'
    133 }
    134 }
    135 }
    136
    137
    138 p first.deep_merge3(second)
    139 #=> {:data=>{:name=>{:middle=>"you", :first=>"Sam", :last=>"are"}}}
    140
    141 p first.keep_merge(second)
    142 #=> {:data=>{:name=>{:first=>"Sam", :middle=>["I", "you"], :last=>["am", "are"]}}}
  • 相关阅读:
    [JavaScript]Cookie详解(转)
    C#中一些默认的预定义特性
    Web 设计与开发终极资源大全
    C# FileStream 文件读写(转)
    使用Jsonp解决跨域数据访问问题[转]
    针对未安装 adobe flash activex 插件 的 ie 浏览器 自动提示安装
    IE position:relative bug
    linux磁盘操作之sgdisk
    安装 archlinux 之使用 EFI/GPT
    从今开始,多花点时间研究技术
  • 原文地址:https://www.cnblogs.com/JulyZhang/p/1991000.html
Copyright © 2011-2022 走看看