score:0

Accepted answer

Use for-comprehensions instead of imperative-style cycles, they are more natural in Scala. And for your task, there are many ways to do it, one of them is like this:

// transform your data to grid, i.e. Map((row,col) -> value). 
// Do this outside the template and pass the result (so that you get the immutable map as a template input)
val toGrid = {
  currentPage.getList.map{ col => col.cells.map(cell => 
    (cell.rowLabel, col.columnLabel, cell.value)
  )}.flatten.map{ case (row, col, value) => ((row,col)->value) }.toMap
}

@rows = @{toGrid.map{ case ((row,col),value) => row }.toSet.toList.sorted}
@columns = @{toGrid.map{ case ((row,col),value) => col }.toSet.toList.sorted}


<div>
@for(row -> rows) {
    <div class="row">
    @for(col -> columns) {
     <div>@toGrid.get(row,col).getOrElse("")</div> //if you might have missing rows/cols
    }
    </div>
}
</div>

UPDATE. If, for some reason, you can't have Scala class outside the template, then the following should perform better(assuming there are no gaps in rows or columns):

@data = @{currentPage.getList}

@triplets = @{data.map{
  col => col.cells.map(cell => (cell.rowLabel,col.columnLabel,cell.value)
)}.flatten

@rows = @{triplets.groupBy(_._1).map{ case (row,cols) => 
          (row, cols.map{ case (row,col,value) => (col,value) })
}}

<div>
@for((row,cols) -> rows.sortBy(_._1)) {
  <div class="row">
  @for((col,value) -> cols.sortBy(_._1)){
    <div>@value</div>
  }
  </div>
}
</div>

Related Query

More Query from same tag