class JsDuck::Columns

Splits array of items with subitems into roughly equal size groups.

Public Class Methods

new(subitems_field) click to toggle source

Initialized with the name of subitems field.

# File lib/jsduck/columns.rb, line 6
def initialize(subitems_field)
  @header_size = 3
  @subitems_field = subitems_field
end

Public Instance Methods

split(items, n) click to toggle source

Splits the array of items into n chunks so that the sum of largest chunk is as small as possible.

This is a brute-force implementation - we just try all the combinations and choose the best one.

# File lib/jsduck/columns.rb, line 16
def split(items, n)
  if n == 1
    [items]
  elsif items.length <= n
    Array.new(n) {|i| items[i] ? [items[i]] : [] }
  else
    min_max = nil
    min_arr = nil
    i = 0
    while i <= items.length-n
      i += 1
      # Try placing 1, 2, 3, ... items to first chunk.
      # Calculate the remaining chunks recursively.
      cols = [items[0,i]] + split(items[i, items.length], n-1)
      max = max_sum(cols)
      # Is this the optimal solution so far? Remember it.
      if !min_max || max < min_max
        min_max = max
        min_arr = cols
      end
    end
    min_arr
  end
end

Private Instance Methods

max_sum(cols) click to toggle source
# File lib/jsduck/columns.rb, line 43
def max_sum(cols)
  cols.map {|col| sum(col) }.max
end
sum(arr) click to toggle source

Finds the total size of items in array

The size of one item is it's number of classes + the space for header

# File lib/jsduck/columns.rb, line 50
def sum(arr)
  arr.reduce(0) {|sum, item| sum + item[@subitems_field].length + @header_size }
end