| 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