Sunday, January 16, 2011

Ruby: Array of Hashes to 2-D Array

Quick Ruby trick.

It is often useful to convert an Array of Hashes (representing a table of objects) to an Array of column names (table header) and an Array of rows (table data). The canonical example would be taking the result of a DB query (ala Sequel) and displaying it in an HTML table (ala DataTables).

Without further ado, here is a proper map/inject one-liner:

array.inject( [data.first.keys, []] ) { |memo, row| memo[1] << memo[0].map { |key| row[key] } ; memo }

A 2-dimensional Array is returned. The first dimension contains the column names, and the second contains the row data (in the same order as the column names, which is the tricky part as Hash#keys can return the keys in any order).

The columns can be sorted (or otherwise ordered specifically) by manipulating data.first.keys when it is initially stored in memo[0].

Example of usage:

irb > data = [ { a: 1, b: 2, c: 3 }, { c: 9, b: 8, a: 7 } ]
irb >  cols, rows = data.inject( [data.first.keys, []] ) { |arr, row| arr[1] << arr[0].map { |key| row[key] } ; arr }
irb > cols
 => [:a, :b, :c]
irb > rows
 => [[1, 2, 3], [7, 8, 9]]

No comments:

Post a Comment