class Burner::Library::Collection::Pivot
Take an array of objects and pivot a key into multiple keys. It essentially takes all the values for a key and creates N number of keys (one per value.) Under the hood it uses HashMath's Record and Table classes: github.com/bluemarblepayroll/hash_math
An example of a normalized dataset that could be pivoted:
records = [
{ patient_id: 1, key: :first_name, value: 'bozo' }, { patient_id: 1, key: :last_name, value: 'clown' }, { patient_id: 2, key: :first_name, value: 'frank' }, { patient_id: 2, key: :last_name, value: 'rizzo' },
]
Using the following job configuration:
config = {
unique_key: :patient_id
}
Once ran through this job, it would set the register to:
records = [
{ patient_id: 1, first_name: 'bozo', last_name: 'clown' }, { patient_id: 2, first_name: 'frank', last_name: 'rizzo' },
]
Expected Payload input: array of objects. Payload output: An array of objects.
Constants
- DEFAULT_PIVOT_KEY
- DEFAULT_PIVOT_VALUE_KEY
Attributes
insensitive[R]
non_pivoted_keys[R]
other_keys[R]
pivot_key[R]
pivot_value_key[R]
resolver[R]
unique_keys[R]
Public Class Methods
new( unique_keys:, insensitive: false, name: '', other_keys: [], pivot_key: DEFAULT_PIVOT_KEY, pivot_value_key: DEFAULT_PIVOT_KEY_VALUE, register: DEFAULT_REGISTER, separator: '' )
click to toggle source
Calls superclass method
Burner::JobWithRegister::new
# File lib/burner/library/collection/pivot.rb, line 54 def initialize( unique_keys:, insensitive: false, name: '', other_keys: [], pivot_key: DEFAULT_PIVOT_KEY, pivot_value_key: DEFAULT_PIVOT_KEY_VALUE, register: DEFAULT_REGISTER, separator: '' ) super(name: name, register: register) @insensitive = insensitive || false @pivot_key = pivot_key.to_s @pivot_value_key = pivot_value_key.to_s @resolver = Objectable.resolver(separator: separator) @unique_keys = Array(unique_keys) @other_keys = Array(other_keys) @non_pivoted_keys = @unique_keys + @other_keys freeze end
Public Instance Methods
perform(output, payload)
click to toggle source
# File lib/burner/library/collection/pivot.rb, line 77 def perform(output, payload) objects = array(payload[register]) table = make_table(objects) output.detail("Pivoting #{objects.length} object(s)") output.detail("By key: #{pivot_key} and value: #{pivot_value_key}") objects.each { |object| object_to_table(object, table) } pivoted_objects = table.to_a.map(&:fields) output.detail("Resulting dataset has #{pivoted_objects.length} object(s)") payload[register] = pivoted_objects end
Private Instance Methods
make_key(value)
click to toggle source
# File lib/burner/library/collection/pivot.rb, line 101 def make_key(value) insensitive ? value.to_s.downcase : value end
make_key_map(objects)
click to toggle source
# File lib/burner/library/collection/pivot.rb, line 109 def make_key_map(objects) objects.each_with_object({}) do |object, key_map| key = resolver.get(object, pivot_key) unique_key = make_key(key) key_map[unique_key] ||= Set.new key_map[unique_key] << key end end
make_record(objects)
click to toggle source
# File lib/burner/library/collection/pivot.rb, line 120 def make_record(objects) key_map = make_key_map(objects) keys = non_pivoted_keys + key_map.values.map(&:first) HashMath::Record.new(keys) end
make_row_id(object)
click to toggle source
# File lib/burner/library/collection/pivot.rb, line 105 def make_row_id(object) unique_keys.map { |k| make_key(resolver.get(object, k)) } end
make_table(objects)
click to toggle source
# File lib/burner/library/collection/pivot.rb, line 127 def make_table(objects) HashMath::Table.new(make_record(objects)) end
object_to_table(object, table)
click to toggle source
# File lib/burner/library/collection/pivot.rb, line 131 def object_to_table(object, table) row_id = make_row_id(object) non_pivoted_keys.each do |key| value = resolver.get(object, key) table.add(row_id, key, value) end key_to_use = resolve_key(object) value_to_use = resolver.get(object, pivot_value_key) table.add(row_id, key_to_use, value_to_use) self end
resolve_key(object)
click to toggle source
# File lib/burner/library/collection/pivot.rb, line 95 def resolve_key(object) key_to_use = resolver.get(object, pivot_key) make_key(key_to_use) end