user257941
user257941

Reputation:

Display data in columns not rows using Ruby on Rails

I would like to display data in Columns rather than Rows in my web page.

What is the most efficient way to do this using Ruby on Rails?

Many thanks for your help!

Upvotes: 1

Views: 4574

Answers (4)

orion3
orion3

Reputation: 9935

Here's my solution. It takes an array, say ["a", "b", "c", "d"] and converts it into this array: [["a", "b"], ["c"], ["d"]] which is then easy to use to display data in columns.

def categories_in_columns(categories, number_of_groups=3)
  groups = []
  elements_per_column       = categories.size / number_of_groups
  extra_elements            = categories.size % number_of_groups
  has_extra_elements        = (extra_elements > 0 ? 1 : 0)

  0.upto(number_of_groups-1).each do |i|
    groups[i] = []
    while groups[i].size < (elements_per_column + has_extra_elements)
      groups[i] << categories.shift
      extra_elements -= 1 if groups[i].size > elements_per_column
    end
    has_extra_elements = 0 if extra_elements == 0
    groups[i].compact!
  end
  groups.delete_if { |i| i.empty? }
end

And specs for it:

it "arranges categories into columns" do
  categories_in_columns(["a", "b", "c", "d", "e"]).should == [["a", "b"], ["c", "d"], ["e"]]
  categories_in_columns(["a", "b", "c", "d"]     ).should == [["a", "b"], ["c"], ["d"]]
  categories_in_columns(["a", "b", "c"]          ).should == [["a"], ["b"], ["c"]]
  categories_in_columns(["a", "b"]               ).should == [["a"], ["b"]]
  categories_in_columns(["a"]                    ).should == [["a"]]
end

Upvotes: 0

Veger
Veger

Reputation: 37906

Simple solution would be to 'rotate' the information, using an array. Like this (pseudo) code (cannot check if atm)
Controller code:

@stuffs = Stuff.find(:all)
@rotated = []
@rotated[0] = [] # Stuff column0
@rotated[1] = [] # Stuff column1
# etc
index = 0
# Now put the stuff in an array for easy(ier) access
@stuffs.each do |stuff|
  @rotated[0][index] = stuff.detail0
  @rotated[1][index] = stuff.detail1
  index += 1
end

In your View you'd need something like this:

<table>
Table head here!
<% 2.times do |row| %>  # Build table (we have 2 stuff details, hence the 2 here)
  <tr>
  <% index.times do |column| %>
    <td><%= @rotated[row][column] %></td>
  <% end %>
  </tr>
<% end %>
<table>

There are of course better solution, but this seems the most simple/general to me. To rotate some data from some Model.

Like others said with more information we can help you probably much better!

Upvotes: 1

Mark Brittingham
Mark Brittingham

Reputation: 28865

If you are pulling the data from a database, you should consider using the PIVOT operator (in SQL Server at least - I'm not sure about SQLLite or MySQL). This way, you could still use "normal" UI methods and still show the data in columns rather than rows. Just a thought...

Upvotes: 0

Eric
Eric

Reputation: 2549

Adapted from an earlier, similar question/answer:

def rotate(matrix)
  columns = matrix.first.size
  rows = matrix.size
  result = []
  columns.times { |y|
    result[y] = []
    rows.times { |x|
      result[y][x] = matrix[x][y]
    }
  }
  result
end

I believe this may be called "transposition," since rather than rotating the array, you really just want to make row 1 into column 1 and so forth. That is, if you rotated a quarter-turn counterclockwise, array[0][0] would wind up in the lower left-hand corner. The above implementation assumes you still want [0][0] to remain in the upper left:

1 2 3 4
5 6 7 8
9 0 a b

1 5 9
2 6 0
3 7 a
4 8 b

I'm also assuming all of the rows have the same number of elements/columns.

Oh hey, and wouldn't you know it: Array#transpose...

<%= render :partial => 'mytable', :collection => @array.transpose %> # untested

Upvotes: 0

Related Questions