Class: One::Pivoter

Inherits:
Object
  • Object
show all
Includes:
Observable
Defined in:
lib/one/pivoter.rb

Overview

Class that can be used for mining data from lists of objects.

Instance Method Summary collapse

Instance Method Details

#multi_pivot(list, *pivots) ⇒ Hash

Runs multiple pivots against a list of Objects.

Examples:

Multi-pivot a list of numbers

list = [1,2,3,4,5,6,7,8,9]
pivots = []

pivots << lambda do |i|
  key = "less than or equal to 5" if i <= 5
  key ||= "greater than 5"
end

pivots << lambda do |i|
  key = "greater than or equal to 3" if i >= 3
  key ||= "less than 3"
end

# note the last pivot is an options Hash
pivots << {:delimiter => " & "}

pivoter = One::Pivot.new
result = pivoter.multi_pivot(list, *pivots) 

# the result will be a Hash with the following structure
{
  "less than or equal to 5 & greater than or equal to 3" => [3, 4, 5], 
  "less than or equal to 5 & less than 3" => [1, 2], 
  "greater than 5 & greater than or equal to 3" => [6, 7, 8, 9]
}

Parameters:

  • list (Array<Object>)

    The list to run the pivots against

  • pivots (Array<Proc, One::Pivot>)

    An argument list that accepts N number of pivots.<br /> The last pivot in the list can be an options Hash for the multi_pivot operation.<br /> Supported options are:<br />

    • :delimiter, The delimiter to use between pivot keys. Defaults to ‘[PIVOT]’]

Returns:

  • (Hash)

    The pivoted results



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/one/pivoter.rb', line 93

def multi_pivot(list, *pivots)
  options = pivots.pop if pivots.last.is_a?(Hash)
  options ||= {}
  delimiter = options[:delimiter] || "[PIVOT]"
  pivoted = nil
  pass = 0

  while pivots.length > 0
    p = pivots.shift
    
    # handle the case where the pivots are One::Pivot objects
    pivot_options = {}
    if p.is_a?(One::Pivot)
      pivot_options[:identifier] = p.identifier
      p = p.pivot_proc
    end

    if pass == 0
      pivoted = pivot(list, pivot_options, &p)
    else
      new_pivoted = {}
      pivoted.each do |old_key, old_list|
        tmp_pivoted = pivot(old_list, pivot_options, &p)
        tmp_pivoted.each do |key, list|
          new_key = "#{safe_key(old_key)}#{delimiter}#{safe_key(key)}"
          new_pivoted[new_key] = list
        end
      end
      pivoted = new_pivoted
    end

    pass += 1
  end

  pivoted
end

#pivot(list, options = {}) {|item| ... } ⇒ Hash

Pivots a list of Objects grouping them into an organized Hash.

Examples:

Pivot a list of numbers into 2 groups, those less than or equal to 5 and those greater than 5

list = [1,2,3,4,5,6,7,8,9]
result = pivot(list) {|num| num <=5 }

# the result will be a Hash with the following structure
{
  true=>[1, 2, 3, 4, 5],
  false=>[6, 7, 8, 9] 
}

Parameters:

  • list (Array<Object>)

    The list to pivot

  • options (optional, Hash) (defaults to: {})

    Options to pivot with

Options Hash (options):

  • :identifier (Object)

    A name that uniquely identifies the pivot operation

Yields:

  • (item)

    The block passed to pivot will be called for each item in the list

Yield Parameters:

  • item (Object)

    An item in the list

Yield Returns:

  • (Object)

    The value returned from the pivot block will serve as the key in the pivot results

Returns:

  • (Hash)

    The pivoted results



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/one/pivoter.rb', line 29

def pivot(list, options={}, &block)
  pivoted = {}
  list.each do |item|
    value = yield(item)

    # notify observers that a pivot block was just called
    identifier = options[:identifier] || "#{item.hash}:#{block.hash}"
    changed
    notify_observers(identifier, item, value) 

    if value.is_a?(Array)
      if value.empty?
        pivoted[nil] ||= []
        pivoted[nil] << item 
      else
        value.each do |val|
          pivoted[val] ||= []
          pivoted[val] << item 
        end
      end
    else
      pivoted[value] ||= []
      pivoted[value] << item 
    end
  end

  pivoted
end