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.