Skip to content

Instantly share code, notes, and snippets.

@chrisberkhout
Created April 28, 2011 04:13
Show Gist options
  • Save chrisberkhout/945786 to your computer and use it in GitHub Desktop.
Save chrisberkhout/945786 to your computer and use it in GitHub Desktop.
Extension to Ruport's Data::Table to do in-memory joins
class Ruport::Data::Table
def left_outer_join(right_table, field)
left_table = self
result = left_table.sub_table { |row| false }
new_col_names = right_table.column_names.reject { |i| i == field.to_s }
result.add_columns new_col_names
right_table_by_field = {}
right_table.each { |right_row|
right_table_by_field[right_row.send(field)] = [] if right_table_by_field[right_row.send(field)].nil?
right_table_by_field[right_row.send(field)] << right_row
}
left_table.each { |left_row|
if right_row_matches = right_table_by_field[left_row.send(field)]
right_row_matches.each { |right_matching_row|
result << left_row.data.merge(right_matching_row)
}
else
result << left_row.data
end
}
result
end
def left_outer_join!(right_table, field)
result = self.left_outer_join(right_table, field)
@column_names = result.column_names
@data = result.data
self
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment