33

I am using Groovy's handy MarkupBuilder to build an HTML page from various source data.

One thing I am struggling to do nicely is build an HTML table and apply different style classes to the first and last rows. This is probably best illustrated with an example...

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

In the <tbody> section, I would like to set the class of the <tr> element to be something different depending whether the current item in myList is the first or the last item.

Is there a nice Groovy-ified way to do this without resorting to something manual to check item indexes against the list size using something like eachWithIndex{}?

tomato
  • 3,373
  • 1
  • 25
  • 33

3 Answers3

56

You could use

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

if(it == myList.last()) {
   // Last element
}
sbglasius
  • 3,104
  • 20
  • 28
  • Nice tip, didn't know about those methods. – xlson Oct 25 '10 at 08:24
  • 7
    Just remember, that first() and last() only works on List, not Map or Set (as per http://groovy.codehaus.org/groovy-jdk/) – sbglasius Oct 26 '10 at 07:34
  • I guess it doesn't work on Set is enough since the reason you can't do it on a map is because each iterates over an EntrySet. Upvote. – Gepsens Jan 13 '12 at 14:34
  • and what about eachRow for sql query results? will your solution work in this case? – altern Jan 30 '13 at 13:38
  • 1
    @altern eachRow will probably not work, but if you call sql.rows("some query") this returns a List and here you should be able to call first() and last(), but I have not tried. Check the GDK here: http://groovy.codehaus.org/api/groovy/sql/Sql.html – sbglasius Feb 05 '13 at 09:47
  • Excellent answer, worked for me!!! congratulations for 50 votes!!! – Amuk Saxena Mar 12 '20 at 14:42
18

The answer provided by sbglasius may lead to incorrect result like when the list contains redundants elements so an element from inside the list may equals the last one.

I'm not sure if sbglasius could use is() instead of == but a correct answer could be :

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

  if(i ==  myList.size()-1) {
   // Last element
  }
}
Nouaman Harti
  • 213
  • 2
  • 4
2

if (it.after.value != null) { ...... }

Works for maps

John Allen
  • 159
  • 4