Class: DataMapper::Validations::OrderedHash
- Includes:
- Enumerable
- Defined in:
- lib/dm-validations/support/ordered_hash.rb
Overview
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 = 1 hsh = 2 hsh = 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.
Class Method Summary collapse
-
.[](*args) ⇒ Object
-- TODO is this needed? Doesn't the super class do this? ++.
-
.alpha(*args, &block) ⇒ Object
Alternate to #new which creates a dictionary sorted by key.
-
.auto(*args) ⇒ Object
Alternate to #new which auto-creates sub-dictionaries as needed.
-
.new_by(*args, &blk) ⇒ Object
Like #new but the block sets the order.
Instance Method Summary collapse
- #<<(kv) ⇒ Object
- #==(hsh2) ⇒ Object
- #[](k) ⇒ Object
-
#[]=(k, i = nil, v = nil) ⇒ Object
Store operator.
- #clear ⇒ Object
- #delete(key) ⇒ Object
- #delete_if ⇒ Object
- #dup ⇒ Object
- #each ⇒ Object (also: #each_pair)
- #each_key ⇒ Object
- #each_value ⇒ Object
- #empty? ⇒ Boolean
- #fetch(k, *a, &b) ⇒ Object
- #first ⇒ Object
- #has_key?(key) ⇒ Boolean
-
#initialize(*args, &blk) ⇒ OrderedHash
constructor
New Dictiionary.
- #insert(i, k, v) ⇒ Object
- #inspect ⇒ Object
- #invert ⇒ Object
- #key?(key) ⇒ Boolean
- #keys ⇒ Object
- #last ⇒ Object
- #length ⇒ Object (also: #size)
- #merge(hsh2) ⇒ Object
- #order ⇒ Object
-
#order_by(&block) ⇒ Object
Keep dictionary sorted by a specific sort order.
-
#order_by_key ⇒ Object
Keep dictionary sorted by key.
-
#order_by_value ⇒ Object
Keep dictionary sorted by value.
- #pop ⇒ Object
- #push(k, v) ⇒ Object
- #reject(&block) ⇒ Object
- #reject!(&block) ⇒ Object
- #reorder ⇒ Object
- #replace(hsh2) ⇒ Object
- #reverse ⇒ Object
- #reverse! ⇒ Object
- #select ⇒ Object
- #shift ⇒ Object
- #store(a, b) ⇒ Object
- #to_a ⇒ Object
- #to_h ⇒ Object
- #to_hash ⇒ Object
- #to_json ⇒ Object
- #to_s ⇒ Object
- #unshift(k, v) ⇒ Object
- #update(hsh2) ⇒ Object (also: #merge!)
- #values ⇒ Object
Constructor Details
#initialize(*args, &blk) ⇒ OrderedHash
New Dictiionary.
136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 136 def initialize(*args, &blk) @order = [] @order_by = nil if blk dict = self # This ensure autmatic key entry effect the oblk = lambda{ |hsh, key| blk[dict,key] } # dictionary rather then just the interal hash. @hash = Hash.new(*args, &oblk) else @hash = Hash.new(*args) end end |
Class Method Details
.[](*args) ⇒ Object
-- TODO is this needed? Doesn't the super class do this? ++
88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 88 def [](*args) hsh = new if Hash === args[0] hsh.replace(args[0]) elsif (args.size % 2) != 0 raise ArgumentError, "odd number of elements for Hash" else while !args.empty? hsh[args.shift] = args.shift end end hsh end |
.alpha(*args, &block) ⇒ Object
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 }
119 120 121 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 119 def alpha(*args, &block) new(*args, &block).order_by_key end |
.auto(*args) ⇒ Object
Alternate to #new which auto-creates sub-dictionaries as needed.
d = Dictionary.auto
d["a"]["b"]["c"] = "abc" #=> { "a"=>{"b"=>{"c"=>"abc"}}}
128 129 130 131 132 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 128 def auto(*args) #AutoDictionary.new(*args) leet = lambda { |hsh, key| hsh[key] = new(&leet) } new(*args, &leet) end |
.new_by(*args, &blk) ⇒ Object
Like #new but the block sets the order.
104 105 106 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 104 def new_by(*args, &blk) new(*args).order_by(&blk) end |
Instance Method Details
#<<(kv) ⇒ Object
323 324 325 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 323 def <<(kv) push( *kv ) end |
#==(hsh2) ⇒ Object
205 206 207 208 209 210 211 212 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 205 def ==(hsh2) if hsh2.is_a?( Dictionary ) @order == hsh2.order && @hash == hsh2.instance_variable_get("@hash") else false end end |
#[](k) ⇒ Object
214 215 216 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 214 def [] k @hash[ k ] end |
#[]=(k, i = nil, v = nil) ⇒ Object
229 230 231 232 233 234 235 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 229 def []=(k, i=nil, v=nil) if v insert(i,k,v) else store(k,i) end end |
#clear ⇒ Object
247 248 249 250 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 247 def clear @order = [] @hash.clear end |
#delete(key) ⇒ Object
252 253 254 255 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 252 def delete( key ) @order.delete( key ) @hash.delete( key ) end |
#delete_if ⇒ Object
273 274 275 276 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 273 def delete_if order.clone.each { |k| delete k if yield(k,@hash[k]) } self end |
#dup ⇒ Object
348 349 350 351 352 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 348 def dup a = [] each{ |k,v| a << k; a << v } self.class[*a] end |
#each ⇒ Object Also known as: each_pair
267 268 269 270 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 267 def each order.each { |k| yield( k,@hash[k] ) } self end |
#each_key ⇒ Object
257 258 259 260 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 257 def each_key order.each { |k| yield( k ) } self end |
#each_value ⇒ Object
262 263 264 265 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 262 def each_value order.each { |k| yield( @hash[k] ) } self end |
#empty? ⇒ Boolean
393 394 395 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 393 def empty? @hash.empty? end |
#fetch(k, *a, &b) ⇒ Object
218 219 220 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 218 def fetch(k, *a, &b) @hash.fetch(k, *a, &b) end |
#first ⇒ Object
380 381 382 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 380 def first @hash[order.first] end |
#has_key?(key) ⇒ Boolean
397 398 399 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 397 def has_key?(key) @hash.has_key?(key) end |
#insert(i, k, v) ⇒ Object
237 238 239 240 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 237 def insert( i,k,v ) @order.insert( i,k ) @hash.store( k,v ) end |
#inspect ⇒ Object
342 343 344 345 346 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 342 def inspect ary = [] each {|k,v| ary << k.inspect + "=>" + v.inspect} '{' + ary.join(", ") + '}' end |
#invert ⇒ Object
288 289 290 291 292 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 288 def invert hsh2 = self.class.new order.each { |k| hsh2[@hash[k]] = k } hsh2 end |
#key?(key) ⇒ Boolean
401 402 403 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 401 def key?(key) @hash.key?(key) end |
#keys ⇒ Object
284 285 286 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 284 def keys order end |
#last ⇒ Object
384 385 386 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 384 def last @hash[order.last] end |
#length ⇒ Object Also known as: size
388 389 390 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 388 def length @order.length end |
#merge(hsh2) ⇒ Object
361 362 363 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 361 def merge( hsh2 ) self.dup.update(hsh2) end |
#order ⇒ Object
148 149 150 151 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 148 def order reorder if @order_by @order end |
#order_by(&block) ⇒ Object
Keep dictionary sorted by a specific sort order.
154 155 156 157 158 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 154 def order_by( &block ) @order_by = block order self end |
#order_by_key ⇒ Object
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.
173 174 175 176 177 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 173 def order_by_key @order_by = lambda { |k,v| k } order self end |
#order_by_value ⇒ Object
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 }
190 191 192 193 194 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 190 def order_by_value @order_by = lambda { |k,v| v } order self end |
#pop ⇒ Object
337 338 339 340 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 337 def pop key = order.last key ? [key,delete(key)] : nil end |
#push(k, v) ⇒ Object
327 328 329 330 331 332 333 334 335 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 327 def push( k,v ) unless @hash.include?( k ) @order.push( k ) @hash.store( k,v ) true else false end end |
#reject(&block) ⇒ Object
294 295 296 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 294 def reject( &block ) self.dup.delete_if(&block) end |
#reject!(&block) ⇒ Object
298 299 300 301 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 298 def reject!( &block ) hsh2 = reject(&block) self == hsh2 ? nil : hsh2 end |
#reorder ⇒ Object
197 198 199 200 201 202 203 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 197 def reorder if @order_by assoc = @order.collect{ |k| [k,@hash[k]] }.sort_by(&@order_by) @order = assoc.collect{ |k,v| k } end @order end |
#replace(hsh2) ⇒ Object
303 304 305 306 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 303 def replace( hsh2 ) @order = hsh2.order @hash = hsh2.hash end |
#reverse ⇒ Object
376 377 378 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 376 def reverse dup.reverse! end |
#reverse! ⇒ Object
371 372 373 374 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 371 def reverse! @order.reverse! self end |
#select ⇒ Object
365 366 367 368 369 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 365 def select ary = [] each { |k,v| ary << [k,v] if yield k,v } ary end |
#shift ⇒ Object
308 309 310 311 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 308 def shift key = order.first key ? [key,delete(key)] : super end |
#store(a, b) ⇒ Object
242 243 244 245 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 242 def store( a,b ) @order.push( a ) unless @hash.has_key?( a ) @hash.store( a,b ) end |
#to_a ⇒ Object
405 406 407 408 409 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 405 def to_a ary = [] each { |k,v| ary << [k,v] } ary end |
#to_h ⇒ Object
430 431 432 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 430 def to_h @hash.dup end |
#to_hash ⇒ Object
426 427 428 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 426 def to_hash @hash.dup end |
#to_json ⇒ Object
411 412 413 414 415 416 417 418 419 420 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 411 def to_json buf = "[" map do |k,v| buf << k.to_json buf << ", " buf << v.to_json end.join(", ") buf << "]" buf end |
#to_s ⇒ Object
422 423 424 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 422 def to_s self.to_a.to_s end |
#unshift(k, v) ⇒ Object
313 314 315 316 317 318 319 320 321 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 313 def unshift( k,v ) unless @hash.include?( k ) @order.unshift( k ) @hash.store( k,v ) true else false end end |
#update(hsh2) ⇒ Object Also known as: merge!
354 355 356 357 358 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 354 def update( hsh2 ) hsh2.each { |k,v| self[k] = v } reorder self end |
#values ⇒ Object
278 279 280 281 282 |
# File 'lib/dm-validations/support/ordered_hash.rb', line 278 def values ary = [] order.each { |k| ary.push @hash[k] } ary end |