Class: Table

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/table.rb

Overview

A table is a basically a combination of an array and a hash.

Actually a possibly easier way to think of them would be as Arrays that have some metadata in the form of a hash.

You can also access symbolized hash keys with dot notation, making them really convenient for a lot of things.

For instance:

t = Table[ 1, 2, 3, 4, { :a => "1", :b => "2" }, 7, 8 ]
t #=> Table[1, 2, 3, 4, 7, 8, {:b=>"2", :a=>"1"}]

t.size #=> 8
t.b #=> "2"

t.b = Table[ 255, 0, 0, { :color => "red" } ]
t.b.color #=> "red"
r, b, g = *t.b
print r, g, b #=> 25500

t #=> Table[1, 2, 3, 4, 7, 8, {:b=>Table[255, 0, 0, {:color=>"red"}], :a=>"1", :c=>"3"}]

t << %{ a b c d }
t.last #=> ["a", "b", "c", "d"]
t[ -3 ] #=> 7

t #=> Table[1, 2, 3, 4, 7, 8, ["a", "b", "c", "d"], {:b=>Table[255, 0, 0, {:color=>"red"}], :a=>"1", :c=>"3"}]

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Table

Returns a new instance of Table


42
43
44
45
46
# File 'lib/table.rb', line 42

def initialize *args
  @values = []
  @records = {}
  process *args
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth_id, *args) ⇒ Object (private)

if an accessor is called that doesn't exist, the key => value are added into the table


332
333
334
335
336
337
# File 'lib/table.rb', line 332

def method_missing meth_id, *args
  name = meth_id.id2name
  if key = name[ /(\w+)=/, 1 ]
    process_hash key.to_sym => args.first
  end
end

Class Method Details

.[](*args) ⇒ Object

takes a comma separated list of arrays and hashes and returns a table

t = Table[ 1, 2, 3, 4, { :a => 3, :b => 5 }, 7, 8, { :c => 33 } ]
t #=> Table[1, 2, 3, 4, 7, 8, {:a=>3, :b=>5, :c=>33}]

38
39
40
# File 'lib/table.rb', line 38

def self.[] *args
  new *args
end

Instance Method Details

#+(other) ⇒ Object

combines 2 tables

t = Table[ :a => 4, :b => 5 ] + Table[ 1, 2, 3, 4, { :c => 4 } ]

t.pairs #=> { :a => 4, :b => 5, :c => 4 }
t.to_a #=> [ 1, 2, 3, 4 ]

188
189
190
191
# File 'lib/table.rb', line 188

def + other
  values = self.to_a + other.to_a 
  Table[ self.pairs, other.pairs, *values ]
end

#<<(arg) ⇒ Object Also known as: push

adds a hash or value to a table

t = Table[ 1, 2, 3 ]

t << { :a => 4, :b => 4 }
t.pairs #=> { :a => 4, :b => 4 }

t << 40000
t.to_a #=> [ 1, 2, 3, 40000 ]

115
116
117
# File 'lib/table.rb', line 115

def << arg
  process arg
end

#[](key, *rest) ⇒ Object

returns the value corresponding to the index or key

t = Table[ 1, 2, "string", { :a => 4, :b => 5 }, 3, 4 ]
t[ 2 ] #=> "string"
t[ :a ] #=> 4

symbolized keys are also accessible via dot notation:

t.a #=> 4
t.b #=> 5

array slicing can also be performed:

t[ 1, 2 ] #=> [2, "string"]
t[ 1..4 ] #=> [2, "string", 3, 4]

63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/table.rb', line 63

def [] key, *rest
  return @values.slice( key, *rest ) if rest.any?

  case key
    when Range
      @values.slice key
    when Integer
      @values[ key ]
    else
      @records[ key ]
  end
end

#[]=(key, value) ⇒ Object

updates the value for a given key or index if no entry exists for the given key or index then one is created

t = Table[ :a => "abcde", :b => 44332211 ]

t[ :a ] = 43
t[ :a ] #=> 43

t[ 0 ] = 54
t.first #=> 54

note that like an array, if you insert a value into a table at an index that doesn't yet exist, any gaps will be filled in with nil such as:

t[ 5 ] = 100
t.to_a #=> [ 54, nil, nil, nil, 100 ]

symbolized keys also have setters so that you can use dot notation:

t.a = "bbcec"
t.a #=> "bbcec"

98
99
100
101
102
103
104
# File 'lib/table.rb', line 98

def []= key, value
  if key.is_a? Integer
    @values[ key ] = value
  else
    process_hash key => value
  end
end

#delete(key) ⇒ Object

deletes a key or index from a table

t = Table[ 1000, 2000, 3000, { :a => 50, :b => 60 } ] 

t.delete 1 #=> 2000
t.delete :b #=> 60
t #=> Table[1000, 3000, {:a=>50}]

174
175
176
177
178
179
180
# File 'lib/table.rb', line 174

def delete key
  if key.kind_of? Integer
    @values.delete_at key
  else
    @records.delete key
  end
end

#each(&block) ⇒ Object

iterate through each of the array values


220
221
222
# File 'lib/table.rb', line 220

def each &block
  @values.each &block
end

#each_key(&block) ⇒ Object

iterate through the hash keys in the table

t = Table[ 1, 2, { :a => "cat", :b => "dog" } ]

t.each_key { | k | print k }
#=> ab

256
257
258
# File 'lib/table.rb', line 256

def each_key &block
  @records.each_key &block
end

#each_pair(&block) ⇒ Object

iterate through the key => value pairs in the table

t = Table[ 1, 2, { :a => "cat", :b => "dog" } ]

t.each_pair { | k, v | print k, v }
#=> bdogacat

246
247
248
# File 'lib/table.rb', line 246

def each_pair &block
  @records.each_pair &block
end

#firstObject

returns the first non pair item in the table

t = Table[ { :a => 4 }, 1, 2, 3, 4, { :b => 4, :c => 23 } ]
t.first #=> 1

197
198
199
# File 'lib/table.rb', line 197

def first
  @values.first
end

#insert(key, *args) ⇒ Object

insert an element into a table at a key or index

if an index is used, multiple values can be added at that location:

t = Table[ 1, 2, 3, 4 ]
t.insert 2, 1000, 2000, 3000
t #=> Table[1, 2, 1000, 2000, 3000, 3, 4]

t.insert 4, 1000000
t #=> Table[1, 2, 1000, 2000, 1000000, 3000, 3, 4]

when a key is used, the functionality is identical to #[]=:

t.insert :a, "apple"
t.insert :b, "banana"
t.a #=> "apple"
t.b #=> "banana"
t => Table[1, 2, 1000, 2000, 1000000, 3000, 3, 4, {:b=>"banana", :a=>"apple"}]

139
140
141
142
143
144
145
# File 'lib/table.rb', line 139

def insert key, *args
  if key.kind_of? Integer
    @values.insert key, *args
  else
    process_hash key => args.first
  end
end

#inspectObject


284
285
286
287
288
289
290
291
292
# File 'lib/table.rb', line 284

def inspect
  hsh = pairs
  str = []

  str << map { | item | item.inspect } if any?
  str << "{#{ hsh.map { | key, val | "#{ key.inspect }=>#{ val.inspect }" }.join( ", " ) }}" if hsh.any?

  "Table[#{ str.join( ", " ) }]"
end

#keysObject

return an array of all hash keys in the table

t = Table[ 1, 2, { :a => 55, :b => 77 }, 3, { :c => 22 } ]
t.keys #=> [ :a, :b, :c ]

272
273
274
# File 'lib/table.rb', line 272

def keys
  @records.keys
end

#lastObject

returns the last non pair item in the table

t = Table[ { :a => 4 }, 1, 2, 3, 4, { :b => 4, :c => 23 } ]
t.last #=> 4

205
206
207
# File 'lib/table.rb', line 205

def last
  @values.last
end

#pairsObject

returns a hash of all key => value pairs inside the table

t = Table[ 1, { :a => 4 }, 2, { :b => 543 } ]
t.pairs #=> { :a => 4, :b => 543 }

264
265
266
# File 'lib/table.rb', line 264

def pairs
  @records
end

#popObject

removes and returns the last non pair element

t = Table[ 1, 2, 3 ]

t.pop #=> 3
t.size #=> 2

153
154
155
# File 'lib/table.rb', line 153

def pop
  @values.pop
end

#shiftObject

removes and returns the first non pair element

t = Table[ 1, 2, 3 ]

t.shift #=> 1
t.size #=> 2

163
164
165
# File 'lib/table.rb', line 163

def shift
  @values.shift
end

#sizeObject Also known as: length

returns the length of all integer indexes

t = Table[ 1, 2, { :b => 4 }, 3, 4 ]
t.size #=> 4

213
214
215
# File 'lib/table.rb', line 213

def size
  @values.size
end

#slice(*args) ⇒ Object

slice a table like an array

t = Table[ 2, 23, 54, { :a => 4 }, 49 ]
t[ 2..4 ] #=> [ 54, 49 ]

236
237
238
# File 'lib/table.rb', line 236

def slice *args
  @values.slice *args
end

#sort(&block) ⇒ Object

sort the array values

t = Table[ 2, 23, 54, { :a => 4 }, 49 ]
t.sort #=> [ 2, 23, 49, 54 ]

228
229
230
# File 'lib/table.rb', line 228

def sort &block
  @values.sort &block
end

#valuesObject

returns an array of all hash values in the table

t = Table[ 1, 2, { :a => 55, :b => 77 }, 3, { :c => 22 } ]
t.values #=> [ 55, 77, 22 ]

280
281
282
# File 'lib/table.rb', line 280

def values
  @records.values
end