2014-06-23 59 views
1

我正在使用Scala和Play框架。給定一個可迭代的Widgets我可以很容易地通過他們循環,並打印出來,如下所示(使用@,因爲這是一個播放模板內,但可以爲這個問題的緣故被忽略):Scala編寫分塊迭代器

@for(widget <- widgets) { 
    <div>My widget: @widget</div> 
} 

現在假設我有一個列布局,我需要顯示每行3個小部件。說我願意HTML輸出如下:

<div class="row"> 
    <div>widget</div> 
    <div>widget</div> 
    <div>widget</div> 
</div> 
<div class="row"> 
    <div>widget</div> 
    <div>widget</div> 
    <div>widget</div> 
</div> 
<div class="row"> 
    <div>widget</div>  
</div> 

我想寫一個「分塊」的迭代器來實現這一點,以便國防部檢查(或但其實現的),可以內化。因此,換句話說,我認爲這將是很好,如果我可以這樣寫:

@chunk(3) { 
    <div class="row"> <!-- gets printed once per chunk --> 

    @for(widget <- widgets) { // gets called for each widget in widgets 
     <div>@widget</div> 
    } 

    </div> <!-- gets printed once per chunk --> 
} 

但是,這不是一個正確的方式,這樣的事情可能會被調用:塊調用需要有小工具的背景下,這樣可以正確調用「內部」迭代(每個塊大小一次)。我不確定在Scala中執行實現的最佳方式是什麼。

當然,替代方案只是編寫一個循環與索引,並進行國防部檢查。但不要認爲這將是一個解決方案的清潔。在Play的模板引擎中找不到像這樣的內容。例如,Freemarker提供了一個chunked operation

回答

2

斯卡拉collection API有你的背影grouped

假設您在範圍內有widgets: List[Widget]

@for(group <- widgets.grouped(3)) { 
    <div class="row"> 
    @for(widget <- group) { 
     <div>@widget</div> 
    } 
    </div> 
} 

grouped(3)將返回在Iterator[List[Widget]],其中每個List[Widget]的尺寸爲3 - 這正是做你的描述。

畫報與Int S:

scala> List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).grouped(3).foreach(println _) 

List(1, 2, 3) 
List(4, 5, 5) 
List(6, 7, 8) 
List(9, 10) 
+0

這是完美的。謝謝 – oym