使用 JSTL 循环遍历列表列表

Looping through a list of lists using JSTL

我有一份取决于学校代码的课程列表。此课程列表已添加到另一个列表,使其成为列表中的列表。

动作Class:

private List<String> schoolList;
private List<String> socList;
private List<String> sobList;
private List<String> sodList;
private List<String> genlist;
private List<List<String>> courseList = new ArrayList<List<String>>();

@Override
public String execute() {
    FacultyManager fm = new FacultyManager();
    schoolList = fm.getColumn("school_description", "school");

    genlist = fm.getCoursesBySchoolCode("GEN");
    sobList = fm.getCoursesBySchoolCode("SOB");
    socList = fm.getCoursesBySchoolCode("SOC");
    sodList = fm.getCoursesBySchoolCode("SOD");     

    courseList.add(genlist);
    courseList.add(sobList);
    courseList.add(socList);        
    courseList.add(sodList);        

    return SUCCESS;
}

JSP:

<c:forEach var="school" items="${schoolList}" varStatus="ctr">
    <ul>
        <li>${school}
            <ul>
                <c:forEach var="course" items="${courseList}">
                    <li>${course}</li>
                </c:forEach>
            </ul>
        </li>
    </ul>
</c:forEach>

输出

我如何做到输出为:

...等等。

如果你想在列表中迭代列表,你可以通过

<c:forEach var="school" items="${schoolList}" varStatus="ctr">
    <ul>
        <li>${school}
            <ul>
                <c:forEach var="course" items="${school}">
                    <li>${course}</li>
                </c:forEach>
            </ul>
        </li>
    </ul>
</c:forEach>

您需要从传递给 jsp 的列表中迭代 inner 列表。

更新

在使用 Map<String, List<String>> 的情况下,您可以将其迭代为

 <c:forEach var="school" items="${schoolList}" varStatus="ctr">
        <ul>
            <li>${school.key}
                <ul>
                    <c:forEach var="course" items="${school.value}">
                        <li>${course}</li>
                    </c:forEach>
                </ul>
            </li>
        </ul>
    </c:forEach>

您可以使用 keyvalueMap

中获取值

您正在一遍又一遍地迭代所有学校的整个课程列表,从而重复相同的输出,就像您多次调用 courseList.toString() 方法一样。

您应该迭代当前学校的具体课程列表,这很可能(但您的问题中没有说明)取决于外部的当前迭代索引<c:forEach> 循环。这又在学校列表迭代索引的导出 ctr 变量(从零开始)的 index 属性 中捕获。

因此,您应该根据当前学校迭代 courseList 列表的特定列表。假设您使用的是 EL2.2+.

,您可以通过调用 courseList.get(ctr.index) 来完成此操作

这全部产生:

<c:forEach var="school" items="${schoolList}" varStatus="ctr">
    <ul>
        <li>${school}
            <ul>
                <c:forEach var="course" items="${courseList.get(ctr.index)}">
                    <li>${course}</li>
                </c:forEach>
            </ul>
        </li>
    </ul>
</c:forEach>

也就是说,List<List<String>> 听起来不是一个好的模型选择。例如,如果您更改插入顺序,您将看到错误的课程。 Map<String, List<String>> 构造更适合您的域模型,因为它可用于将学校名称明确映射到课程名称列表。

另一个要认真考虑的选项是对象的使用(你到底是在做OOP)。您应该远离纯字符串并进入对象域。首先,调查以下 class 层次结构:

public class Course {
    //...
    private School school;
    //...
}

public class School {
    //...
    private List<Course> courses;
    //...
}