Freemarker Iterating Over Hashmap Keys

Freemarker iterating over hashmap keys

Edit: Don't use this solution with FreeMarker 2.3.25 and up, especially not .get(prop). See other answers.

You use the built-in keys function, e.g. this should work:

<#list user?keys as prop>
${prop} = ${user.get(prop)}
</#list>

Iterating over HashMap in Freemarker template displays map's methods

Basically, I managed to iterate through the map only after wrapping it in SimpleMapModel like so:

   public static String runRequest(HttpServletRequest request, HttpServletResponse response) {
Map<String, Long> typesToCount = getTypesToCount();
request.setAttribute("types", new SimpleMapModel(typesToCount, new DefaultObjectWrapper())));
return HttpFinals.RETURN_SUCCESS;
}

and int ftl template:

   <#list requestAttributes.types?keys as key>
<tr>
<td>${key}</td>
<td>${requestAttributes.types[key]}</td>
</tr>
</#list>

Freemarker iterating over hashmap keys in a list

This should be better, you forgot to change user to account, probably while copying from here ;)

<table>
<#list accounts as account>
<tr>
<#list account?keys as prop>
<td>${account[prop]}</td>
</#list>
</tr>
</#list>
</table>

Freemarker iterating over hashmap in list of map

If you put your code into the model bean in a method

  public HashMap<String, Object> getRoot() {
// ... your code
return root;
}

then you can access the list of maps under the abc key like this:

[
<#list root['abc'] as map>
{
<#list map?keys as key>
${key}: ${map[key]}
</#list>
}
</#list>
]

Instead of root['abc'], you could also use root.abc, but the first version stresses that abc is a hash map key, not a property of root.

This is the resulting output:

[
{
two: a
one: a
three: a
}
{
two: b
one: b
three: b
}
{
two: c
one: c
three: c
}
]

Iterating over the same HashMap keys twice. Is the order guaranteed to be same?

From the HashMap documentation:

This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.

In theory this means that there are absolutely no guarantees about the order of the keys between subsequent iterations even if you do them immediatly one after the other(the time has changed), you can also see this question.

In practice and after checking Java 8 source code HashMap internally has a Node<K,V>[] table array and all it does during iteration is going over it. So if you will do 2 subsequent invocations of node_map?keys without any changes to the map, I can say with confidence that it will be in the same order. I will never actually write code that depends on it though because it's not guaranteed by the contract.

some hashes maintain a meaningful order

This means that you can use other Map implementations that do guarantee consistent ordering for example TreeMap or LinkedHashMap. If you populate node_map with LinkedHashMap then it will be guaranteed to be consistent not only in practice but also in theory(this is what you should do if you want to rely on it).

How To Iterate HashMap in FreeMarker?

FTL doesn't have a Map type. It has a so called hash type, which is just something that can have subvariables, and ?keys lists the subvariable names (which should be strings). What keys you see depends on the objectWrapper configuration setting of FreeMarker, and in this case you see the Map keys mixed with the method names... because, you could write stuff like groups_time.get(foo) etc. and so get is a subvariable. Even if you configure FreeMarker so that it doesn't mix in the methods names (that's the default BTW), you will have trouble using the [] operator with non-String keys. Anyway, since here you have access to the Map API, just use that. <#list time.groups_time.entrySet() as keyValuePair>..., etc.



Related Topics



Leave a reply



Submit