Class: ObjectTable::Grouped

Inherits:
Object
  • Object
show all
Includes:
TableChild
Defined in:
lib/object_table/grouped.rb

Constant Summary collapse

DEFAULT_VALUE_PREFIX =
'v_'

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TableChild

#__group_cls__, #__static_view_cls__, #__table_cls__, #__view_cls__

Constructor Details

#initialize(parent, *names, &grouper) ⇒ Grouped

Returns a new instance of Grouped.



8
9
10
11
12
# File 'lib/object_table/grouped.rb', line 8

def initialize(parent, *names, &grouper)
  @parent = parent
  @grouper = grouper
  @names = names
end

Class Method Details

._generate_name(prefix, existing_names) ⇒ Object



82
83
84
85
86
# File 'lib/object_table/grouped.rb', line 82

def self._generate_name(prefix, existing_names)
  regex = Regexp.new(Regexp.quote(prefix) + '(\d+)')
  i = existing_names.map(&regex.method(:match)).compact.map{|match| match[-1].to_i}.max || -1
  "#{prefix}#{i + 1}"
end

Instance Method Details

#_groupsObject



15
16
17
18
19
20
21
22
# File 'lib/object_table/grouped.rb', line 15

def _groups
  names, keys = _keys()
  groups = (0...@parent.nrows).zip(keys).group_by{|row, key| key}
  groups.each do |k, v|
    groups[k] = NArray.to_na(v.map(&:first))
  end
  [names, groups]
end

#_keysObject



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/object_table/grouped.rb', line 24

def _keys
  if @names.empty?
    keys = @parent.apply(&@grouper)
    raise 'Group keys must be hashes' unless keys.is_a?(Hash)
    keys = ObjectTable::BasicGrid.new.replace keys
  else
    keys = ObjectTable::BasicGrid[@names.map{|n| [n, @parent.get_column(n)]}]
  end

  keys._ensure_uniform_columns!(@parent.nrows)
  names = keys.keys
  keys = keys.values.map(&:to_a).transpose
  [names, keys]
end

#apply(&block) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/object_table/grouped.rb', line 58

def apply(&block)
  names, groups = _groups()
  value_key = self.class._generate_name(DEFAULT_VALUE_PREFIX, names).to_sym

  data = groups.map do |k, v|
    keys = names.zip(k)
    value = __group_cls__.new(@parent, Hash[keys], v).apply &block

    if value.is_a?(ObjectTable::TableMethods)
      value = value.columns
    end

    grid = case value
    when ObjectTable::BasicGrid
      ObjectTable::BasicGrid[keys].merge!(value)
    else
      ObjectTable::BasicGrid[keys + [[value_key, value]]]
    end
    grid._ensure_uniform_columns!
  end

  __table_cls__.stack(*data)
end

#each(&block) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/object_table/grouped.rb', line 49

def each(&block)
  names, groups = _groups()
  groups.each do |k, v|
    keys = names.zip(k)
    __group_cls__.new(@parent, Hash[keys], v).apply &block
  end
  @parent
end