Class Dictionary
In: lib/extlib/dictionary.rb
Parent: Object
Dictionary Enumerable dot/f_29.png

Dictionary

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.

Usage

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

Usage Notes

  • You can use order_by 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.

Methods

<<   ==   []   []   []=   alpha   auto   clear   delete   delete_if   dup   each   each_key   each_pair   each_value   empty?   fetch   first   has_key?   insert   inspect   invert   key?   keys   last   length   merge   merge!   new   new_by   order   order_by   order_by_key   order_by_value   pop   push   reject   reject!   reorder   replace   reverse   reverse!   select   shift   size   store   to_a   to_h   to_hash   to_json   to_s   unshift   update   values  

Included Modules

Enumerable

Public Class methods

[Source]

     # 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 }

[Source]

     # 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"}}}

[Source]

     # 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.

[Source]

     # 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

Like new but the block sets the order.

[Source]

     # File lib/extlib/dictionary.rb, line 104
104:     def new_by(*args, &blk)
105:       new(*args).order_by(&blk)
106:     end

Public Instance methods

[Source]

     # File lib/extlib/dictionary.rb, line 323
323:   def <<(kv)
324:     push( *kv )
325:   end

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 214
214:   def [] k
215:     @hash[ k ]
216:   end

Store operator.

  h[key] = value

Or with additional index.

 h[key,index] = value

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 247
247:   def clear
248:     @order = []
249:     @hash.clear
250:   end

[Source]

     # File lib/extlib/dictionary.rb, line 252
252:   def delete( key )
253:     @order.delete( key )
254:     @hash.delete( key )
255:   end

[Source]

     # 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

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 267
267:   def each
268:     order.each { |k| yield( k,@hash[k] ) }
269:     self
270:   end

[Source]

     # File lib/extlib/dictionary.rb, line 257
257:   def each_key
258:     order.each { |k| yield( k ) }
259:     self
260:   end
each_pair()

Alias for each

[Source]

     # File lib/extlib/dictionary.rb, line 262
262:   def each_value
263:     order.each { |k| yield( @hash[k] ) }
264:     self
265:   end

[Source]

     # File lib/extlib/dictionary.rb, line 393
393:   def empty?
394:     @hash.empty?
395:   end

[Source]

     # File lib/extlib/dictionary.rb, line 218
218:   def fetch(k, *a, &b)
219:     @hash.fetch(k, *a, &b)
220:   end

[Source]

     # File lib/extlib/dictionary.rb, line 380
380:   def first
381:     @hash[order.first]
382:   end

[Source]

     # File lib/extlib/dictionary.rb, line 397
397:   def has_key?(key)
398:     @hash.has_key?(key)
399:   end

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 401
401:   def key?(key)
402:     @hash.key?(key)
403:   end

[Source]

     # File lib/extlib/dictionary.rb, line 284
284:   def keys
285:     order
286:   end

[Source]

     # File lib/extlib/dictionary.rb, line 384
384:   def last
385:     @hash[order.last]
386:   end

[Source]

     # File lib/extlib/dictionary.rb, line 388
388:   def length
389:     @order.length
390:   end

[Source]

     # File lib/extlib/dictionary.rb, line 361
361:   def merge( hsh2 )
362:     self.dup.update(hsh2)
363:   end
merge!( hsh2 )

Alias for update

[Source]

     # File lib/extlib/dictionary.rb, line 148
148:   def order
149:     reorder if @order_by
150:     @order
151:   end

Keep dictionary sorted by a specific sort order.

[Source]

     # File lib/extlib/dictionary.rb, line 154
154:   def order_by( &block )
155:     @order_by = block
156:     order
157:     self
158:   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.

[Source]

     # 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 }

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 337
337:   def pop
338:     key = order.last
339:     key ? [key,delete(key)] : nil
340:   end

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 294
294:   def reject( &block )
295:     self.dup.delete_if(&block)
296:   end

[Source]

     # File lib/extlib/dictionary.rb, line 298
298:   def reject!( &block )
299:     hsh2 = reject(&block)
300:     self == hsh2 ? nil : hsh2
301:   end

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 303
303:   def replace( hsh2 )
304:     @order = hsh2.order
305:     @hash = hsh2.hash
306:   end

[Source]

     # File lib/extlib/dictionary.rb, line 376
376:   def reverse
377:     dup.reverse!
378:   end

[Source]

     # File lib/extlib/dictionary.rb, line 371
371:   def reverse!
372:     @order.reverse!
373:     self
374:   end

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 308
308:   def shift
309:     key = order.first
310:     key ? [key,delete(key)] : super
311:   end
size()

Alias for length

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 405
405:   def to_a
406:     ary = []
407:     each { |k,v| ary << [k,v] }
408:     ary
409:   end

[Source]

     # File lib/extlib/dictionary.rb, line 430
430:   def to_h
431:     @hash.dup
432:   end

[Source]

     # File lib/extlib/dictionary.rb, line 426
426:   def to_hash
427:     @hash.dup
428:   end

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 422
422:   def to_s
423:     self.to_a.to_s
424:   end

[Source]

     # 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

[Source]

     # File lib/extlib/dictionary.rb, line 354
354:   def update( hsh2 )
355:     hsh2.each { |k,v| self[k] = v }
356:     reorder
357:     self
358:   end

[Source]

     # File lib/extlib/dictionary.rb, line 278
278:   def values
279:     ary = []
280:     order.each { |k| ary.push @hash[k] }
281:     ary
282:   end

[Validate]