Scala编写了一个chunked迭代器

时间:2014-06-23 17:09:08

标签: scala playframework-2.0

我正在使用Scala和Play Framework。给定I Widgets Iterable,我可以轻松地遍历它们并按如下方式打印它们(使用@,因为这是在Play模板中,但是为了这个问题可以忽略它):

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

我正在尝试编写一个“chunked”迭代器来实现这一点,以便mod检查(或者它实现的)可以内化。换句话说,我认为如果我能写下来会很好:

@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 -->  
}

但这不是一个正确的方法,可以调用这样的东西:块调用需要具有Widgets的上下文,以便可以正确调用“内部”迭代(每个块一次)。我不确定在Scala中继续执行的最佳方法是什么。

另一种方法当然是编写带索引的循环并进行模式检查。但是,不要认为这将是一个清洁的解决方案。我在Play的模板引擎中找不到这样的东西。例如,Freemarker确实提供了chunked operation

1 个答案:

答案 0 :(得分:2)

Scala集合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)