在 Groovy each 闭包中检测第一个和最后一个项目

Posted

技术标签:

【中文标题】在 Groovy each 闭包中检测第一个和最后一个项目【英文标题】:Detecting first and last item inside a Groovy each closure在 Groovy each 闭包中检测第一个和最后一个项目 【发布时间】:2011-04-30 01:52:32 【问题描述】:

我正在使用 Groovy 方便的 MarkupBuilder 从各种源数据构建 html 页面。

我正在努力做好的一件事是构建一个 HTML 表格并将不同的样式类应用于第一行和最后一行。这可能最好用一个例子来说明......

table() 
  thead() 
    tr()
      th('class':'l name', 'name')
      th('class':'type', 'type')
      th('description')
    
  
  tbody() 
    // Add a row to the table for each item in myList
    myList.each 
      tr('class' : '????????') 
        td('class':'l name', it.name)
        td('class':'type', it.type)
        td(it.description)
      
    
     

<tbody> 部分,我想将<tr> 元素的类设置为不同的,具体取决于myList 中的当前项是第一项还是最后一项。

有没有一种很好的 Groovy 化方法可以做到这一点,而无需借助诸如 eachWithIndex 之类的手动检查项目索引与列表大小的关系?

【问题讨论】:

【参考方案1】:

你可以使用

if(it == myList.first()) 
   // First element


if(it == myList.last()) 
   // Last element

【讨论】:

不错的提示,不知道那些方法。 请记住,first() 和 last() 仅适用于 List,而不适用于 Map 或 Set(根据 groovy.codehaus.org/groovy-jdk) 我猜它在 Set 上不起作用就足够了,因为你不能在地图上做它的原因是因为每个都迭代了一个 EntrySet。点赞。 sql 查询结果的 eachRow 呢?您的解决方案在这种情况下是否有效? @altern eachRow 可能不起作用,但是如果您调用 sql.rows("some query") 这将返回一个 List 并且在这里您应该能够调用 first() 和 last( ),但我没有尝试过。在此处查看 GDK:groovy.codehaus.org/api/groovy/sql/Sql.html【参考方案2】:

if (it.after.value != null) ……

适用于地图

【讨论】:

【参考方案3】:

sbglasius 提供的答案可能会导致不正确的结果,例如当列表包含冗余元素时,列表内的元素可能等于最后一个。

我不确定 sbglasius 是否可以使用 is() 代替 ==,但正确的答案可能是:

myList.eachWithIndex elt, i ->
  if(i == 0) 
   // First element
  

  if(i ==  myList.size()-1) 
   // Last element
  

【讨论】:

感谢eachWithIndex :) 很好

以上是关于在 Groovy each 闭包中检测第一个和最后一个项目的主要内容,如果未能解决你的问题,请参考以下文章

Groovy

Groovy循环控制 ( Number 注入函数实现循环 | times 函数 | upto 函数 | downto 函数 | step 函数 | 闭包作为最后参数可写在外面 )

Groovy集合遍历 ( 使用集合的 collect 循环遍历集合并根据指定闭包规则生成新集合 | 代码示例 )

如何在 Groovy 中动态覆盖类的“each”方法?

Groovymap 集合 ( map 集合遍历 | 使用 map 集合的 each 方法遍历 map 集合 | 代码示例 )

Groovy闭包中的this,owner和delegate