class ReplaceStringJoinOnRangesAST

Public Instance Methods

map(ast) click to toggle source
# File src/simplify/replace_string_join_on_ranges.rb, line 3
def map(ast)
  return ast unless ast.is_a?(Array)
  ast.each do |a| 
    next unless a.is_a?(Array)
    case ast.first
    when :error, :null, :space, :prefix, :boolean_true, :boolean_false, :number, :string
      next
    when :sheet_reference, :table_reference, :local_table_reference
      next
    else
      map(a)
    end
  string_join(ast) if ast[0] == :string_join
  end
  ast
end
select_from(maybe_array, row_index, column_index) click to toggle source
# File src/simplify/replace_string_join_on_ranges.rb, line 51
def select_from(maybe_array, row_index, column_index)
  return map(maybe_array) unless maybe_array.first == :array
  row = maybe_array[row_index+1]
  return [:error, "#VALUE!"] unless row
  cell = row[column_index+1]
  return [:error, "#VALUE!"] unless cell
  map(cell)
end
string_join(ast) click to toggle source
# File src/simplify/replace_string_join_on_ranges.rb, line 20
def string_join(ast)
  strings = ast[1..-1]
  # Make sure there is actually a conversion to do
  return unless strings.any? { |s| s.first == :array }
  # Now work out the largest dimensions
  # Arrays look like this [:array, [:row, 1, 2, 3], [:row, 4, 5, 6]]
  max_rows = 0
  max_columns = 0
  strings.each do |s|
    next unless s.first == :array
    r = s.length - 1 # -1 beause first element is :array
    c = r > 0 ? s[1].length - 1 : 0 # check if rows, if there are, columns is length of that array -1 for initial :row symbol
    max_columns = c if c > max_columns
    max_rows = r if r > max_rows
  end

  result = [:array]
  (0...max_rows).each do |row_index|
    row = [:row]
    (0...max_columns).each do |column_index|
      column = [:string_join]
      strings.each do |string|
        column << select_from(string, row_index, column_index)
      end
      row << column
    end
    result << row
  end
  ast.replace(result)
end