1

:이 질문을 위해서스칼라에서 우아한 방법으로 표의 List 속성 (셀 값)으로 객체 (열)의 목록을 렌더링 하시겠습니까? 같은 스칼라 템플릿의 모델 객체 (매트릭스)의 목록 렌더링 할 수있는 "최고"방법은 무엇

public class Column extends Model { 

    public String columnLabel; 

    @OneToMany 
    public List cells; 
} 

public class Cell extends Model { 
    public String rowLabel; //index 
    public BigDecimal value; 
} 

는 cells.size()와 rowLabel는 대한 일치 모든 열 객체. 컨트롤러는 List [Column]을 뷰에 반환합니다. 나는 도우미와 배열에 목록을 변환하는 것을 시도했다 :

@matrix(list: List[Column]):Array = @{ 

    var rowCount = list.head.values.size() 
    var colCount = list.size() 
    var m = Array.ofDim[String](rowCount,colCount) 
    for (i <- 0 to rowCount-1) { 
     for (j <- 0 to colCount-1) { 
      matrix(i)(j) = list(j).cells(i).value.toString(); 
     } 
    } 
    return m; 
} 

을 다음보기에서 :

<div> 
    @for(i <- 1 to currentPage.getList.head.values.size()) { 
     <div class="row"> 
      @for(j <- 1 to currentPage.getList.size()) { 
       <div class="col-md-1">@matrix(currentPage.getList)(i)(j)</div> 
      } 
     </div> 
    } 
</div> 

하지만

물론 이것은 단지 행렬 값 및하지를 열이나 행을 추출한다 레이블.

목록 목록에 사용할 수있는 스칼라 배열의 장점이 있습니까? 배열 크기가 약이므로 효율성이 중요합니다. 20 열 x 2000 행. 아니면 컨트롤러에서 매트릭스 행을보기에서 변환하려고 시도하지 않고 명시 적으로 반환하도록하는 것이 더 나은 방법입니까?

답변

0

명령형주기가 아닌 for-comprehensions를 사용하면 스칼라에서 더 자연 스럽습니다. 그리고 당신의 작업은, 그것을 할 수있는 많은 방법이 있습니다, 그 중 하나는 다음과 같이이다 :

// 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. 어떤 이유에서든 템플릿 외부에 스칼라 클래스를 사용할 수 없으면 다음과 같이 수행해야합니다 (행 또는 열에 간격이 없다고 가정).

@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> 
+0

나는 그것이 내게 줄 것이라고 생각합니다. 공통 rowLabel을 가진 행렬을 렌더링하는 것이 아니라 각 열의 값을 가진 행을 렌더링하는 것이 아니라 각 열 객체에 대한 행을 만듭니다. – geeforce

+0

아, 알았어요. 대답을 업데이트 할 것입니다 ... – Ashalynd

+0

실제 삼중 항을 얻기 위해 나는 .map {case (col, (row, value)) => (col, row, value)}'를 zip에 추가해야만했습니다. groupBy :'생성자에서 컴파일 오류로 문제가 발생하여 예상되는 유형으로 인스턴스화 할 수 없습니다. 발견 : (T1, T2, T3) 필요 : List [(String, String, java.math.BigDecimal)] – geeforce