lib/in_columns/columnizer.rb in in_columns-0.1.0 vs lib/in_columns/columnizer.rb in in_columns-0.2.0
- old
+ new
@@ -2,27 +2,59 @@
class Columnizer
def initialize(elements)
@elements = elements
end
- def columns(number_of_columns)
- columns = create_columns(number_of_columns)
- distribute_elements(columns)
+ # Returns the necessary rows to distribute elements into the desired number
+ # of columns
+ #
+ # The result is a multidimensional array, so that:
+ #
+ # Columnizer.new(['a', 'b', 'c']).distribute(2)
+ # #=> [['a', 'c'], ['b', nil]]
+ def distribute(number_of_columns)
+ return [] if elements.empty?
+ distribute_elements(number_of_columns)
end
private
attr_reader :elements
- def create_columns(number_of_columns)
- (1..number_of_columns).collect { [] }
+ def distribute_elements(number_of_columns)
+ number_of_rows = (number_of_elements.to_f / number_of_columns).ceil
+ counts = row_counts(number_of_columns)
+
+ columns = []
+ elements_to_distribute = elements.dup
+
+ while !elements_to_distribute.empty?
+ size_of_column = counts[columns.size]
+ elements_for_column = elements_to_distribute.shift(size_of_column)
+ columns << elements_for_column
+ end
+
+ # Convert the columns to rows
+ first_column = columns.first
+ rest_columns = columns[1..-1]
+ columns = first_column.zip(*rest_columns)
end
- def distribute_elements(columns)
- elements.each_with_index { |element, index|
- column_number = index % columns.size
- columns[column_number] << element
+ def number_of_elements
+ elements.size
+ end
+
+ # Returns an array with an element for each column containing the number of
+ # rows for that column
+ def row_counts(number_of_columns)
+ per_column = (number_of_elements / number_of_columns).floor
+ counts = [per_column] * number_of_columns
+
+ left_overs = number_of_elements % number_of_columns
+ left_overs.times { |n|
+ counts[n] = counts[n] + 1
}
- columns
+
+ counts
end
end
end