Class | Dictionary |
In: |
lib/more/facets/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 don'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/more/facets/dictionary.rb, line 128 128: def [](*args) 129: hsh = new 130: if Hash === args[0] 131: hsh.replace(args[0]) 132: elsif (args.size % 2) != 0 133: raise ArgumentError, "odd number of elements for Hash" 134: else 135: while !args.empty? 136: hsh[args.shift] = args.shift 137: end 138: end 139: hsh 140: 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/more/facets/dictionary.rb, line 160 160: def alpha(*args, &block) 161: new(*args, &block).order_by_key 162: 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/more/facets/dictionary.rb, line 169 169: def auto(*args) 170: #AutoDictionary.new(*args) 171: leet = lambda { |hsh, key| hsh[key] = new(&leet) } 172: new(*args, &leet) 173: end
New Dictiionary.
# File lib/more/facets/dictionary.rb, line 178 178: def initialize(*args, &blk) 179: @order = [] 180: @order_by = nil 181: if blk 182: dict = self # This ensure autmatic key entry effect the 183: oblk = lambda{ |hsh, key| blk[dict,key] } # dictionary rather then just the interal hash. 184: @hash = Hash.new(*args, &oblk) 185: else 186: @hash = Hash.new(*args) 187: end 188: end
def ==( hsh2 )
return false if @order != hsh2.order super hsh2
end
# File lib/more/facets/dictionary.rb, line 255 255: def ==(hsh2) 256: if hsh2.is_a?( Dictionary ) 257: @order == hsh2.order && 258: @hash == hsh2.instance_variable_get("@hash") 259: else 260: false 261: end 262: end
Store operator.
h[key] = value
Or with additional index.
h[key,index] = value
# File lib/more/facets/dictionary.rb, line 280 280: def []=(k, i=nil, v=nil) 281: if v 282: insert(i,k,v) 283: else 284: store(k,i) 285: end 286: end
# File lib/more/facets/dictionary.rb, line 298 298: def clear 299: @order = [] 300: @hash.clear 301: end
# File lib/more/facets/dictionary.rb, line 303 303: def delete( key ) 304: @order.delete( key ) 305: @hash.delete( key ) 306: end
# File lib/more/facets/dictionary.rb, line 324 324: def delete_if 325: order.clone.each { |k| delete k if yield(k,@hash[k]) } 326: self 327: end
# File lib/more/facets/dictionary.rb, line 406 406: def dup 407: a = [] 408: each{ |k,v| a << k; a << v } 409: self.class[*a] 410: end
# File lib/more/facets/dictionary.rb, line 318 318: def each 319: order.each { |k| yield( k,@hash[k] ) } 320: self 321: end
# File lib/more/facets/dictionary.rb, line 308 308: def each_key 309: order.each { |k| yield( k ) } 310: self 311: end
# File lib/more/facets/dictionary.rb, line 313 313: def each_value 314: order.each { |k| yield( @hash[k] ) } 315: self 316: end
# File lib/more/facets/dictionary.rb, line 268 268: def fetch(k, *a, &b) 269: @hash.fetch(k, *a, &b) 270: end
# File lib/more/facets/dictionary.rb, line 439 439: def first(x=nil) 440: return @hash[order.first] unless x 441: order.first(x).collect { |k| @hash[k] } 442: end
# File lib/more/facets/dictionary.rb, line 459 459: def has_key?(key) 460: @hash.has_key?(key) 461: end
# File lib/more/facets/dictionary.rb, line 288 288: def insert( i,k,v ) 289: @order.insert( i,k ) 290: @hash.store( k,v ) 291: end
# File lib/more/facets/dictionary.rb, line 400 400: def inspect 401: ary = [] 402: each {|k,v| ary << k.inspect + "=>" + v.inspect} 403: '{' + ary.join(", ") + '}' 404: end
# File lib/more/facets/dictionary.rb, line 339 339: def invert 340: hsh2 = self.class.new 341: order.each { |k| hsh2[@hash[k]] = k } 342: hsh2 343: end
# File lib/more/facets/dictionary.rb, line 445 445: def last(x=nil) 446: return @hash[order.last] unless x 447: order.last(x).collect { |k| @hash[k] } 448: end
# File lib/more/facets/dictionary.rb, line 419 419: def merge( hsh2 ) 420: self.dup.update(hsh2) 421: end
# File lib/more/facets/dictionary.rb, line 190 190: def order 191: reorder if @order_by 192: @order 193: 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/more/facets/dictionary.rb, line 217 217: def order_by_key 218: @order_by = lambda { |k,v| k } 219: order 220: self 221: 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/more/facets/dictionary.rb, line 235 235: def order_by_value 236: @order_by = lambda { |k,v| v } 237: order 238: self 239: end
# File lib/more/facets/dictionary.rb, line 395 395: def pop 396: key = order.last 397: key ? [key,delete(key)] : nil 398: end
# File lib/more/facets/dictionary.rb, line 385 385: def push( k,v ) 386: unless @hash.include?( k ) 387: @order.push( k ) 388: @hash.store( k,v ) 389: true 390: else 391: false 392: end 393: end
# File lib/more/facets/dictionary.rb, line 345 345: def reject(&block) 346: self.dup.delete_if(&block) 347: end
# File lib/more/facets/dictionary.rb, line 349 349: def reject!( &block ) 350: hsh2 = reject(&block) 351: self == hsh2 ? nil : hsh2 352: end
# File lib/more/facets/dictionary.rb, line 242 242: def reorder 243: if @order_by 244: assoc = @order.collect{ |k| [k,@hash[k]] }.sort_by(&@order_by) 245: @order = assoc.collect{ |k,v| k } 246: end 247: @order 248: end
# File lib/more/facets/dictionary.rb, line 354 354: def replace(hsh2) 355: case hsh2 356: when Hash 357: @order = hsh2.keys 358: @hash = hsh2 359: else 360: @order = hsh2.order 361: @hash = hsh2.hash 362: end 363: reorder 364: end
# File lib/more/facets/dictionary.rb, line 429 429: def reverse! 430: @order.reverse! 431: self 432: end
# File lib/more/facets/dictionary.rb, line 423 423: def select 424: ary = [] 425: each { |k,v| ary << [k,v] if yield k,v } 426: ary 427: end
# File lib/more/facets/dictionary.rb, line 366 366: def shift 367: key = order.first 368: key ? [key,delete(key)] : super 369: end
# File lib/more/facets/dictionary.rb, line 293 293: def store( a,b ) 294: @order.push( a ) unless @hash.has_key?( a ) 295: @hash.store( a,b ) 296: end
# File lib/more/facets/dictionary.rb, line 467 467: def to_a 468: ary = [] 469: each { |k,v| ary << [k,v] } 470: ary 471: end
# File lib/more/facets/dictionary.rb, line 371 371: def unshift( k,v ) 372: unless @hash.include?( k ) 373: @order.unshift( k ) 374: @hash.store( k,v ) 375: true 376: else 377: false 378: end 379: end