Discussion:
last element in a foreach loop
Philip Mark Donaghy
2003-11-20 11:52:09 UTC
Permalink
Is there a way of knowing when we make the last loop
in a foreach class.

A variable velocityLast would make sense like the
variable velocityCount.

I need this so that I can avoid putting a comma(,)
behind the last element in the list.

How have you resolved this problem?

Thanks for the great techno,
Phil

=====
Java Web Application Architect
mapimage.com - Java and GIS
struts1.1:tomcat4.1.27:linuxRH8

__________________________________
Do you Yahoo!?
Free Pop-Up Blocker - Get it now
http://companion.yahoo.com/
Hans Juergen von Lengerke
2003-11-20 13:19:24 UTC
Permalink
Post by Philip Mark Donaghy
Is there a way of knowing when we make the last loop
in a foreach class.
This is what I use:

#foreach ($item in $items)
#if ($velocityCount == $items.size() - 1)
Last Item: $item
#end
#end

(This assumes that you have configured
directive.foreach.counter.initial.value = 0)
J. B. Rainsberger
2003-11-20 15:49:39 UTC
Permalink
Post by Philip Mark Donaghy
Is there a way of knowing when we make the last loop
in a foreach class.
A variable velocityLast would make sense like the
variable velocityCount.
I need this so that I can avoid putting a comma(,)
behind the last element in the list.
How have you resolved this problem?
The other way around: loop like so.

writeItem
loop starting at item #2
write comma; writeItem
endloop

You /know/ when you're at the first element, which is easier than what
you're trying to do.
--
J. B. Rainsberger,
Diaspar Software Services
http://www.diasparsoftware.com :: +1 416 791-8603
Let's write software that people understand
Shawn Church
2003-11-20 18:51:16 UTC
Permalink
Adding a little more code but avoiding the extra writeItem, you could
also do:

#set($first = true)
#foreach($item in $itemlist)
#if($first)
#set($first = false)
#else
write comma
#end
write $item
#end
Post by J. B. Rainsberger
Post by Philip Mark Donaghy
Is there a way of knowing when we make the last loop
in a foreach class.
A variable velocityLast would make sense like the
variable velocityCount.
I need this so that I can avoid putting a comma(,)
behind the last element in the list.
How have you resolved this problem?
The other way around: loop like so.
writeItem
loop starting at item #2
write comma; writeItem
endloop
You /know/ when you're at the first element, which is easier than what
you're trying to do.
--
J. B. Rainsberger,
Diaspar Software Services
http://www.diasparsoftware.com :: +1 416 791-8603
Let's write software that people understand
---------------------------------------------------------------------
J. B. Rainsberger
2003-11-20 22:38:19 UTC
Permalink
Post by Shawn Church
Adding a little more code but avoiding the extra writeItem, you could
#set($first = true)
#foreach($item in $itemlist)
#if($first)
#set($first = false)
#else
write comma
#end
write $item
#end
But why use more code? The version below captures what we really do:
write an item, then (write a comma, write an item) until there are no
more items. It deals with its special case simply.

The above version is more code, more cyclomatic complexity and less
clear, at least at first glance.

Nothing bad about you, mind... I just think that above solution is
unnecessarily complicated.
Post by Shawn Church
Post by J. B. Rainsberger
writeItem
loop starting at item #2
write comma; writeItem
endloop
--
J. B. Rainsberger,
Diaspar Software Services
http://www.diasparsoftware.com :: +1 416 791-8603
Let's write software that people understand
Tim Colson
2003-11-20 23:52:46 UTC
Permalink
Say J.B. -
Post by J. B. Rainsberger
writeItem
loop starting at item #2
write comma; writeItem
endloop
Uh... no offense, but that's pseudo-code, not a real template snippet.
The various other answers were pretty clear. But this one is clear only
in theory, not sure what the actual template would look like. (Heck, I
don't even know how to start a loop for $LIST_OF_THINGIES at item #2 in
a #foreach.)

Timo
J. B. Rainsberger
2003-11-21 00:12:37 UTC
Permalink
Post by Tim Colson
Say J.B. -
Post by J. B. Rainsberger
writeItem
loop starting at item #2
write comma; writeItem
endloop
Uh... no offense, but that's pseudo-code, not a real template snippet.
The various other answers were pretty clear. But this one is clear only
in theory, not sure what the actual template would look like. (Heck, I
don't even know how to start a loop for $LIST_OF_THINGIES at item #2 in
a #foreach.)
Well, I was arguing /clear/, not /legal/. :)

No, it's an excellent point: the discussion's not worth much if I throw
in code that can't work. I'm still getting used to Velocity.

This points to a feature not present in the VTL: the ability to join an
array. I would tend to implement that as a tool rather than try to bend
VTL to my will. Were we talking about JSP, I'd have implemented a custom
tag.

An "if" statement that evaluates one way potentially 99% of the time
(for 100-item list) is questionable and perhaps best eliminated, not to
mention the sheer amount of code one would duplicate if one were to
copy-and-paste that loop rather than implement it in a macro.
--
J. B. Rainsberger,
Diaspar Software Services
http://www.diasparsoftware.com :: +1 416 791-8603
Let's write software that people understand
Shawn Church
2003-11-21 01:19:32 UTC
Permalink
This post might be inappropriate. Click to display it.
Dave Newton
2003-11-21 03:26:41 UTC
Permalink
Post by Shawn Church
A low cyclomatic
complexity contributes to a programs amenability to modification at lower
risk.
This sentence nearly caused me to pull off my own head and reminds me of
a funny web page I recently read about the perils of "academic prose."

:)
Post by Shawn Church
#foreach( $item in $itemlist)
<div class=...>
<tr>
<td nowrap>
<table border="0" cellspacing="0" cellpadding="2">
<tr>
<td><a href="xxx">$item.yyy</a></td>
<td>
<form action="zzz" method="post" name="zzz" >
<input type="hidden" name="aaa" value="$item.yyy">
<input type="image" name=submit.details value="Details"
src="/images/details.gif" border=0 alt="Details">
</form>
</td>
</tr>
</table>
</td>
</tr>
</div>
#end
This example was loosely pulled from one of my actual templates, and there
are in fact over 80 html lines involved within this particular #foreach
block. If I decide to add a column in the table or to otherwise change its
presentation, I would stand a good chance of breaking the page. There's no
good reason I would want to duplicate these lines.
That's why they invented macros, I suppose, which has the additional
benefit (in theory, of course) of not embedding stuff far down a page,
and might also allow a similar presentation style across pages.

Dave
Shawn Church
2003-11-21 06:05:13 UTC
Permalink
Post by Shawn Church
Post by Shawn Church
A low cyclomatic
complexity contributes to a programs amenability to
modification at lower
Post by Shawn Church
risk.
This sentence nearly caused me to pull off my own head and reminds me of
a funny web page I recently read about the perils of "academic prose."
:)
But, but, well, um, yes, ok, I see your point.
Post by Shawn Church
Post by Shawn Church
This example was loosely pulled from one of my actual
templates, and there
Post by Shawn Church
are in fact over 80 html lines involved within this particular #foreach
block. If I decide to add a column in the table or to
otherwise change its
Post by Shawn Church
presentation, I would stand a good chance of breaking the page.
There's no
Post by Shawn Church
good reason I would want to duplicate these lines.
That's why they invented macros, I suppose, which has the additional
benefit (in theory, of course) of not embedding stuff far down a page,
and might also allow a similar presentation style across pages.
I will give this a try, but I usually #parse things like this. I've used
macros mainly to wrap calls to context tools which require further validity
checking or response handling. I don't normally include any html or other
view-related things in macros, but rather only use them to hide sequences of
necessary but busy Velocity tags. So you are including presentation
elements in macros?

Shawn
Dave Newton
2003-11-21 12:49:17 UTC
Permalink
Post by Shawn Church
Post by Dave Newton
This sentence nearly caused me to pull off my own head and reminds me of
a funny web page I recently read about the perils of "academic prose."
But, but, well, um, yes, ok, I see your point.
;)
Post by Shawn Church
So you are including presentation elements in macros?
Yeah, I do sometimes, as I reuse them a lot... I've never been sure if
that's a good idea or not, really, and I've "lost" view element
definitions at times.

Then I tried naming conventions, like "viewItemRow" and things like
that. It sorta-solved that, and that's where it stands for now :)

Dave
J. B. Rainsberger
2003-11-21 21:00:00 UTC
Permalink
Post by Shawn Church
More cyclomatic complexity? I respectfully disagree.
Um, more if statements means higher cyclomatic complexity, does it not?
Is 1 no longer greater than 0? (It's possible I have the wrong
definition of cyclomatic complexity, but I don't think so...)

<snip/>
Post by Shawn Church
Duplicating sections of code such as 'writeItem' is generally a bad idea,
and one which I tend to avoid if possible. This is true regardless of the
type of code, whether in a Velocity template, Java source, or whatever.
Everything from subroutines and functions in procedural languages to methods
and procedures in more object-oriented languages lend themselves to the
elimination of redundant code. Maybe your 'writeItem' is in fact a single
line, but most commonly for me in the generation of html data streams
<snip />

If I need to be a single line, it becomes a single line. That's why we
have macros, no?
Post by Shawn Church
This example was loosely pulled from one of my actual templates, and there
are in fact over 80 html lines involved within this particular #foreach
block. If I decide to add a column in the table or to otherwise change its
presentation, I would stand a good chance of breaking the page. There's no
good reason I would want to duplicate these lines.
I wouldn't dream of duplicating 80 lines. One line, though, duplicated
within two lines of its duplicate... I think most programmers can handle
that. :)
Post by Shawn Church
My method is only an example, and Barbara's use of $velocityCount is
actually cleaner and preferable in most instances, especially if you are
concerned with the complexity of an #if #else block.
Clearly our opinions differ. That's OK: it makes the world go round.
--
J. B. Rainsberger,
Diaspar Software Services
http://www.diasparsoftware.com :: +1 416 791-8603
Let's write software that people understand
Barbara Baughman
2003-11-20 16:01:38 UTC
Permalink
For comma separations of a list, I use:

#foreach ($item in $items)
#if (velocityCount>1),#end $item
#end

This puts a comma-blank before all but the first $item. To avoid line
breaks, put it all on one line.

Barbara Baughman
X2157
Post by Philip Mark Donaghy
Is there a way of knowing when we make the last loop
in a foreach class.
A variable velocityLast would make sense like the
variable velocityCount.
I need this so that I can avoid putting a comma(,)
behind the last element in the list.
How have you resolved this problem?
Thanks for the great techno,
Phil
=====
Java Web Application Architect
mapimage.com - Java and GIS
struts1.1:tomcat4.1.27:linuxRH8
__________________________________
Do you Yahoo!?
Free Pop-Up Blocker - Get it now
http://companion.yahoo.com/
---------------------------------------------------------------------
Loading...