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
You can use # to set internal sort order.
#<< takes a two element [k,v] array and inserts.
Use ::auto which creates Dictionay sub-entries as needed.
And ::alpha which creates a new Dictionary sorted by key.
# File lib/more/facets/dictionary.rb, line 74 74: def [](*args) 75: hsh = new 76: if Hash === args[0] 77: hsh.replace(args[0]) 78: elsif (args.size % 2) != 0 79: raise ArgumentError, "odd number of elements for Hash" 80: else 81: while !args.empty? 82: hsh[args.shift] = args.shift 83: end 84: end 85: hsh 86: end
Alternate to # 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 106 106: def alpha(*args, &block) 107: new(*args, &block).order_by_key 108: end
Alternate to # 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 115 115: def auto(*args) 116: #AutoDictionary.new(*args) 117: leet = lambda { |hsh, key| hsh[key] = new(&leet) } 118: new(*args, &leet) 119: end
New Dictiionary.
# File lib/more/facets/dictionary.rb, line 124 124: def initialize(*args, &blk) 125: @order = [] 126: @order_by = nil 127: if blk 128: dict = self # This ensure autmatic key entry effect the 129: oblk = lambda{ |hsh, key| blk[dict,key] } # dictionary rather then just the interal hash. 130: @hash = Hash.new(*args, &oblk) 131: else 132: @hash = Hash.new(*args) 133: end 134: end
# File lib/more/facets/dictionary.rb, line 327 327: def <<(kv) 328: push(*kv) 329: end
def ==( hsh2 )
return false if @order != hsh2.order super hsh2
end
# File lib/more/facets/dictionary.rb, line 201 201: def ==(hsh2) 202: if hsh2.is_a?( Dictionary ) 203: @order == hsh2.order && 204: @hash == hsh2.instance_variable_get("@hash") 205: else 206: false 207: end 208: end
# File lib/more/facets/dictionary.rb, line 210 210: def [] k 211: @hash[ k ] 212: end
Store operator.
h[key] = value
Or with additional index.
h[key,index] = value
# File lib/more/facets/dictionary.rb, line 226 226: def []=(k, i=nil, v=nil) 227: if v 228: insert(i,k,v) 229: else 230: store(k,i) 231: end 232: end
# File lib/more/facets/dictionary.rb, line 244 244: def clear 245: @order = [] 246: @hash.clear 247: end
# File lib/more/facets/dictionary.rb, line 249 249: def delete( key ) 250: @order.delete( key ) 251: @hash.delete( key ) 252: end
# File lib/more/facets/dictionary.rb, line 270 270: def delete_if 271: order.clone.each { |k| delete k if yield(k,@hash[k]) } 272: self 273: end
# File lib/more/facets/dictionary.rb, line 352 352: def dup 353: a = [] 354: each{ |k,v| a << k; a << v } 355: self.class[*a] 356: end
# File lib/more/facets/dictionary.rb, line 264 264: def each 265: order.each { |k| yield( k,@hash[k] ) } 266: self 267: end
# File lib/more/facets/dictionary.rb, line 254 254: def each_key 255: order.each { |k| yield( k ) } 256: self 257: end
# File lib/more/facets/dictionary.rb, line 259 259: def each_value 260: order.each { |k| yield( @hash[k] ) } 261: self 262: end
# File lib/more/facets/dictionary.rb, line 401 401: def empty? 402: @hash.empty? 403: end
# File lib/more/facets/dictionary.rb, line 214 214: def fetch(k, *a, &b) 215: @hash.fetch(k, *a, &b) 216: end
# File lib/more/facets/dictionary.rb, line 385 385: def first(x=nil) 386: return @hash[order.first] unless x 387: order.first(x).collect { |k| @hash[k] } 388: end
# File lib/more/facets/dictionary.rb, line 405 405: def has_key?(key) 406: @hash.has_key?(key) 407: end
# File lib/more/facets/dictionary.rb, line 234 234: def insert( i,k,v ) 235: @order.insert( i,k ) 236: @hash.store( k,v ) 237: end
# File lib/more/facets/dictionary.rb, line 346 346: def inspect 347: ary = [] 348: each {|k,v| ary << k.inspect + "=>" + v.inspect} 349: '{' + ary.join(", ") + '}' 350: end
# File lib/more/facets/dictionary.rb, line 285 285: def invert 286: hsh2 = self.class.new 287: order.each { |k| hsh2[@hash[k]] = k } 288: hsh2 289: end
# File lib/more/facets/dictionary.rb, line 409 409: def key?(key) 410: @hash.key?(key) 411: end
# File lib/more/facets/dictionary.rb, line 281 281: def keys 282: order 283: end
# File lib/more/facets/dictionary.rb, line 391 391: def last(x=nil) 392: return @hash[order.last] unless x 393: order.last(x).collect { |k| @hash[k] } 394: end
# File lib/more/facets/dictionary.rb, line 396 396: def length 397: @order.length 398: end
# File lib/more/facets/dictionary.rb, line 365 365: def merge( hsh2 ) 366: self.dup.update(hsh2) 367: end
# File lib/more/facets/dictionary.rb, line 136 136: def order 137: reorder if @order_by 138: @order 139: end
Keep dictionary sorted by a specific sort order.
# File lib/more/facets/dictionary.rb, line 143 143: def order_by( &block ) 144: @order_by = block 145: order 146: self 147: 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 163 163: def order_by_key 164: @order_by = lambda { |k,v| k } 165: order 166: self 167: 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 181 181: def order_by_value 182: @order_by = lambda { |k,v| v } 183: order 184: self 185: end
# File lib/more/facets/dictionary.rb, line 341 341: def pop 342: key = order.last 343: key ? [key,delete(key)] : nil 344: end
# File lib/more/facets/dictionary.rb, line 331 331: def push( k,v ) 332: unless @hash.include?( k ) 333: @order.push( k ) 334: @hash.store( k,v ) 335: true 336: else 337: false 338: end 339: end
# File lib/more/facets/dictionary.rb, line 291 291: def reject(&block) 292: self.dup.delete_if(&block) 293: end
# File lib/more/facets/dictionary.rb, line 295 295: def reject!( &block ) 296: hsh2 = reject(&block) 297: self == hsh2 ? nil : hsh2 298: end
# File lib/more/facets/dictionary.rb, line 188 188: def reorder 189: if @order_by 190: assoc = @order.collect{ |k| [k,@hash[k]] }.sort_by(&@order_by) 191: @order = assoc.collect{ |k,v| k } 192: end 193: @order 194: end
# File lib/more/facets/dictionary.rb, line 300 300: def replace(hsh2) 301: case hsh2 302: when Hash 303: @order = hsh2.keys 304: @hash = hsh2 305: else 306: @order = hsh2.order 307: @hash = hsh2.hash 308: end 309: reorder 310: end
# File lib/more/facets/dictionary.rb, line 380 380: def reverse 381: dup.reverse! 382: end
# File lib/more/facets/dictionary.rb, line 375 375: def reverse! 376: @order.reverse! 377: self 378: end
# File lib/more/facets/dictionary.rb, line 369 369: def select 370: ary = [] 371: each { |k,v| ary << [k,v] if yield k,v } 372: ary 373: end
# File lib/more/facets/dictionary.rb, line 312 312: def shift 313: key = order.first 314: key ? [key,delete(key)] : super 315: end
# File lib/more/facets/dictionary.rb, line 239 239: def store( a,b ) 240: @order.push( a ) unless @hash.has_key?( a ) 241: @hash.store( a,b ) 242: end
# File lib/more/facets/dictionary.rb, line 413 413: def to_a 414: ary = [] 415: each { |k,v| ary << [k,v] } 416: ary 417: end
# File lib/more/facets/dictionary.rb, line 427 427: def to_h 428: @hash.dup 429: end
# File lib/more/facets/dictionary.rb, line 423 423: def to_hash 424: @hash.dup 425: end
# File lib/more/facets/dictionary.rb, line 419 419: def to_s 420: self.to_a.to_s 421: end
# File lib/more/facets/dictionary.rb, line 317 317: def unshift( k,v ) 318: unless @hash.include?( k ) 319: @order.unshift( k ) 320: @hash.store( k,v ) 321: true 322: else 323: false 324: end 325: end
# File lib/more/facets/dictionary.rb, line 358 358: def update( hsh2 ) 359: hsh2.each { |k,v| self[k] = v } 360: reorder 361: self 362: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.