Class | Dictionary |
In: |
lib/extlib/dictionary.rb
|
Parent: | Object |
The Dictionary class is a Hash that preserves order. So it has some array-like extensions also. By defualt a Dictionary object preserves insertion order, but any order can be specified including alphabetical key order.
Just require this file and use Dictionary instead of Hash.
# You can do simply hsh = Dictionary.new hsh['z'] = 1 hsh['a'] = 2 hsh['c'] = 3 p hsh.keys #=> ['z','a','c'] # or using Dictionary[] method hsh = Dictionary['z', 1, 'a', 2, 'c', 3] p hsh.keys #=> ['z','a','c'] # but this doesn't preserve order hsh = Dictionary['z'=>1, 'a'=>2, 'c'=>3] p hsh.keys #=> ['a','c','z'] # Dictionary has useful extensions: push, pop and unshift p hsh.push('to_end', 15) #=> true, key added p hsh.push('to_end', 30) #=> false, already - nothing happen p hsh.unshift('to_begin', 50) #=> true, key added p hsh.unshift('to_begin', 60) #=> false, already - nothing happen p hsh.keys #=> ["to_begin", "a", "c", "z", "to_end"] p hsh.pop #=> ["to_end", 15], if nothing remains, return nil p hsh.keys #=> ["to_begin", "a", "c", "z"] p hsh.shift #=> ["to_begin", 30], if nothing remains, return nil
# File lib/extlib/dictionary.rb, line 88 88: def [](*args) 89: hsh = new 90: if Hash === args[0] 91: hsh.replace(args[0]) 92: elsif (args.size % 2) != 0 93: raise ArgumentError, "odd number of elements for Hash" 94: else 95: while !args.empty? 96: hsh[args.shift] = args.shift 97: end 98: end 99: hsh 100: end
Alternate to new which creates a dictionary sorted by key.
d = Dictionary.alpha d["z"] = 1 d["y"] = 2 d["x"] = 3 d #=> {"x"=>3,"y"=>2,"z"=>2}
This is equivalent to:
Dictionary.new.order_by { |key,value| key }
# File lib/extlib/dictionary.rb, line 119 119: def alpha(*args, &block) 120: new(*args, &block).order_by_key 121: end
Alternate to new which auto-creates sub-dictionaries as needed.
d = Dictionary.auto d["a"]["b"]["c"] = "abc" #=> { "a"=>{"b"=>{"c"=>"abc"}}}
# File lib/extlib/dictionary.rb, line 128 128: def auto(*args) 129: #AutoDictionary.new(*args) 130: leet = lambda { |hsh, key| hsh[key] = new(&leet) } 131: new(*args, &leet) 132: end
New Dictiionary.
# File lib/extlib/dictionary.rb, line 136 136: def initialize(*args, &blk) 137: @order = [] 138: @order_by = nil 139: if blk 140: dict = self # This ensure autmatic key entry effect the 141: oblk = lambda{ |hsh, key| blk[dict,key] } # dictionary rather then just the interal hash. 142: @hash = Hash.new(*args, &oblk) 143: else 144: @hash = Hash.new(*args) 145: end 146: end
# File lib/extlib/dictionary.rb, line 205 205: def ==(hsh2) 206: if hsh2.is_a?( Dictionary ) 207: @order == hsh2.order && 208: @hash == hsh2.instance_variable_get("@hash") 209: else 210: false 211: end 212: end
Store operator.
h[key] = value
Or with additional index.
h[key,index] = value
# File lib/extlib/dictionary.rb, line 229 229: def []=(k, i=nil, v=nil) 230: if v 231: insert(i,k,v) 232: else 233: store(k,i) 234: end 235: end
# File lib/extlib/dictionary.rb, line 252 252: def delete( key ) 253: @order.delete( key ) 254: @hash.delete( key ) 255: end
# File lib/extlib/dictionary.rb, line 273 273: def delete_if 274: order.clone.each { |k| delete k if yield(k,@hash[k]) } 275: self 276: end
# File lib/extlib/dictionary.rb, line 348 348: def dup 349: a = [] 350: each{ |k,v| a << k; a << v } 351: self.class[*a] 352: end
# File lib/extlib/dictionary.rb, line 267 267: def each 268: order.each { |k| yield( k,@hash[k] ) } 269: self 270: end
# File lib/extlib/dictionary.rb, line 257 257: def each_key 258: order.each { |k| yield( k ) } 259: self 260: end
# File lib/extlib/dictionary.rb, line 262 262: def each_value 263: order.each { |k| yield( @hash[k] ) } 264: self 265: end
# File lib/extlib/dictionary.rb, line 218 218: def fetch(k, *a, &b) 219: @hash.fetch(k, *a, &b) 220: end
# File lib/extlib/dictionary.rb, line 237 237: def insert( i,k,v ) 238: @order.insert( i,k ) 239: @hash.store( k,v ) 240: end
# File lib/extlib/dictionary.rb, line 342 342: def inspect 343: ary = [] 344: each {|k,v| ary << k.inspect + "=>" + v.inspect} 345: '{' + ary.join(", ") + '}' 346: end
# File lib/extlib/dictionary.rb, line 288 288: def invert 289: hsh2 = self.class.new 290: order.each { |k| hsh2[@hash[k]] = k } 291: hsh2 292: end
# File lib/extlib/dictionary.rb, line 361 361: def merge( hsh2 ) 362: self.dup.update(hsh2) 363: end
# File lib/extlib/dictionary.rb, line 148 148: def order 149: reorder if @order_by 150: @order 151: end
Keep dictionary sorted by key.
d = Dictionary.new.order_by_key d["z"] = 1 d["y"] = 2 d["x"] = 3 d #=> {"x"=>3,"y"=>2,"z"=>2}
This is equivalent to:
Dictionary.new.order_by { |key,value| key }
The initializer Dictionary#alpha also provides this.
# File lib/extlib/dictionary.rb, line 173 173: def order_by_key 174: @order_by = lambda { |k,v| k } 175: order 176: self 177: end
Keep dictionary sorted by value.
d = Dictionary.new.order_by_value d["z"] = 1 d["y"] = 2 d["x"] = 3 d #=> {"x"=>3,"y"=>2,"z"=>2}
This is equivalent to:
Dictionary.new.order_by { |key,value| value }
# File lib/extlib/dictionary.rb, line 190 190: def order_by_value 191: @order_by = lambda { |k,v| v } 192: order 193: self 194: end
# File lib/extlib/dictionary.rb, line 337 337: def pop 338: key = order.last 339: key ? [key,delete(key)] : nil 340: end
# File lib/extlib/dictionary.rb, line 327 327: def push( k,v ) 328: unless @hash.include?( k ) 329: @order.push( k ) 330: @hash.store( k,v ) 331: true 332: else 333: false 334: end 335: end
# File lib/extlib/dictionary.rb, line 294 294: def reject( &block ) 295: self.dup.delete_if(&block) 296: end
# File lib/extlib/dictionary.rb, line 298 298: def reject!( &block ) 299: hsh2 = reject(&block) 300: self == hsh2 ? nil : hsh2 301: end
# File lib/extlib/dictionary.rb, line 197 197: def reorder 198: if @order_by 199: assoc = @order.collect{ |k| [k,@hash[k]] }.sort_by(&@order_by) 200: @order = assoc.collect{ |k,v| k } 201: end 202: @order 203: end
# File lib/extlib/dictionary.rb, line 303 303: def replace( hsh2 ) 304: @order = hsh2.order 305: @hash = hsh2.hash 306: end
# File lib/extlib/dictionary.rb, line 365 365: def select 366: ary = [] 367: each { |k,v| ary << [k,v] if yield k,v } 368: ary 369: end
# File lib/extlib/dictionary.rb, line 308 308: def shift 309: key = order.first 310: key ? [key,delete(key)] : super 311: end
# File lib/extlib/dictionary.rb, line 242 242: def store( a,b ) 243: @order.push( a ) unless @hash.has_key?( a ) 244: @hash.store( a,b ) 245: end
# File lib/extlib/dictionary.rb, line 405 405: def to_a 406: ary = [] 407: each { |k,v| ary << [k,v] } 408: ary 409: end
# File lib/extlib/dictionary.rb, line 411 411: def to_json 412: buf = "[" 413: map do |k,v| 414: buf << k.to_json 415: buf << ", " 416: buf << v.to_json 417: end.join(", ") 418: buf << "]" 419: buf 420: end
# File lib/extlib/dictionary.rb, line 313 313: def unshift( k,v ) 314: unless @hash.include?( k ) 315: @order.unshift( k ) 316: @hash.store( k,v ) 317: true 318: else 319: false 320: end 321: end