Using JSTL\'s forEach
tag, is it possible to iterate in reverse order?
When you are using forEach
to create an integer loop, you can go forward or backward, but it requires some work. It turns out you cannot do this, for example:
<c:forEach var="i" begin="10" end="0" step="-1">
....
</c:forEach>
because the spec requires the step is positive. But you can always loop in forward order and then use <c:var
to convert the incrementing number into a decrementing number:
<c:forEach var="i" begin="0" end="10" step="1">
<c:var var="decr" value="${10-i}"/>
....
</c:forEach>
However, when you are doing a forEach
over a Collection of any sort, I am not aware of any way to have the objects in reverse order. At least, not without first sorting the elements into reverse order and then using forEach
.
I have successfully navigated a forEach
loop in a desired order by doing something like the following in a JSP:
<%
List list = (List)session.getAttribute("list");
Comparator comp = ....
Collections.sort(list, comp);
%>
<c:forEach var="bean" items="<%=list%>">
...
</c:forEach>
With a suitable Comparator, you can loop over the items in any desired order. This works. But I am not aware of a way to say, very simply, iterate in reverse order the collection provided.
You could reverse the Collection before adding it to your model.
This also means you would not need to do anything in the view layer to achieve your requirement.
We can do this with a little bit trick:-
<c:forEach begin="1" end="10" var="i" step="1">
<c:set var="j" value="${10-i+1}" scope="page"></c:set>
<c:out value="${j}"/>
</c:forEach>
OutPut will be :- 10 9 8 7 6 5 4 3 2 1
You could also consider rolling a custom JSTL function that returned a reversed copy of your list, backed by something like this:
public static <T extends Object> List<T> reverse(List<T> list) {
List<T> copy = Collections.emptyList();
Collections.copy(copy, list);
Collections.reverse(copy);
return copy;
}
Doesn't work for Collections, but as mentioned in another answer, the concept of ordering is a bit vague for some collections.
Building on the answer given by Eddie, I used the following code to iterate over a collection in reverse order.
Given a collection called "list", which stores a list of people.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%-- Keep a reference to the size of the collection --%>
<c:set var="num_people" value="${fn:length(list)}" />
<%-- Iterate through items. Start at 1 to avoid array index out of bounds --%>
<c:forEach var="i" begin="1" end="${num_people}" step="1">
<c:set var="person" value="${list[num_people-i]}" />
${person.name}<br />
</c:forEach>