代码之家  ›  专栏  ›  技术社区  ›  Andy

如何修改Hash以允许Ruby中较短的“Hash[:a,:b]”访问元素“Hash[:a][:b]”?

  •  1
  • Andy  · 技术社区  · 14 年前

    我很乐意通过一个较短的表达式访问多维哈希数组的任何元素

    h = {a: {b: 'c'}}
    
    # default way
    p h[:a][:b] # => "c"
    
    # a nicer way
    p h[:a,:b] # => "c"
    
    # nice assignment
    h[:a,:b] = 1
    p h # => {:a=>{:b=>1}}
    

    我意识到,通过这种方式可以消除将哈希键作为数组的可能性。

    {[:a,:b] => "c"}
    

    因为这是非常罕见的情况,我宁愿减少我的表达式中[]的数量。

    如何做到这一点?


    更新

    好吧,我不清楚。问题是我已经试着定制了 [] []= 方法,但失败了。你能告诉我如何实现这样的功能吗?

    多维数组

    如果您正在寻找类似的数组,请查看 narray 宝石 http://narray.rubyforge.org/

    >> a = NArray.int(5,5)
    => NArrayint5,5: 
    [ [ 0, 0, 0, 0, 0 ], 
      [ 0, 0, 0, 0, 0 ], 
      [ 0, 0, 0, 0, 0 ], 
      [ 0, 0, 0, 0, 0 ], 
      [ 0, 0, 0, 0, 0 ] ]
    >> a[1,2]
    => 0
    >> a[1,2]=1
    => 1
    >> a
    => NArrayint5,5: 
    [ [ 0, 0, 0, 0, 0 ], 
      [ 0, 0, 0, 0, 0 ], 
      [ 0, 1, 0, 0, 0 ], 
      [ 0, 0, 0, 0, 0 ], 
      [ 0, 0, 0, 0, 0 ] ]
    >> a[1,0..4]=1
    => 1
    >> a
    => NArrayint5,5: 
    [ [ 0, 1, 0, 0, 0 ], 
      [ 0, 1, 0, 0, 0 ], 
      [ 0, 1, 0, 0, 0 ], 
      [ 0, 1, 0, 0, 0 ], 
      [ 0, 1, 0, 0, 0 ] ]
    
    2 回复  |  直到 14 年前
        1
  •  3
  •   Andy    14 年前

    我已经修复了我的代码,所以现在它可以工作了

    class AutoHash < Hash
      def initialize *args
        super
        @update, @update_index = args[0][:update], args[0][:update_key] unless 
    args.empty?
      end
    
        def [] key,*args
          if args.count > 0
            self[key][*args]
          else
            if self.has_key? key
              super key
            else
              AutoHash.new :update => self, :update_key => key
            end
          end
        end
    
        def []= *args
          v = args.pop
          k = args.shift
          if args.count > 0
            self[k][*args]= v
          else
            @update[@update_index] = self if @update and @update_index
            super k,v
          end
        end
    end
    

    示例

    a = AutoHash.new
    a[:a][:b][:c] = 123
    a[:a,:b,:c] = 321
    p a # => {:a=>{:b=>{:c=>321}}}
    

    #path 而不是重新定义 [] )

    h[:a][:b][:c] = 123
    p h.path(:a,:b,:c) # => 123
    
    h.path(:a,:b,:c)= 321
    p h #=> {:a=>{:b=>{:c=>321}}}
    
    mypath = [:a,:b,:c]
    p h.path(mypath) #=> 321
    
        2
  •  1
  •   bjg    14 年前

    [] []= 在您选择的类上,包括该语言提供的哈希类。如果修改基类,请小心使用