如何对 Freemarker 序列进行投影以提取 属性?

How to do a projection on Freemarker sequences to extract a property?

假设我在一个 freemarker 变量中有一些对象 container 并且 container.content 给了我一个对象序列(我将称它们为 "things")带有名称和 String getName()访问器。我想从 container.content 序列中生成一个以逗号分隔的名称列表。

如果我已经有了一系列的名字而不是一系列有名字的东西,我可以简单地做 names?join(", ")。有什么简洁的东西可以从 container.content 中提取 .name-s 然后加入它们吗?更一般地说,我正在寻找函数式编程映射(收集、投影)操作,但在文档中没有找到。

我目前尝试过的:

目前,我有 <#list container.content as x>${x.name}<#if x?has_next>, </#if></#list> 来重现 map-then-join 操作,但我发现它相当冗长,而且基本上重新实现 join 对我来说似乎有点奇怪。

之前我有 container.content?join(", "),当然我得到了 "Thing[name=A, otherStuff=...], Thing[name=B, otherStuff=...]" 而不是 "A, B"。我不希望将 Thing#toString 方法修改为仅 return 名称。我想保留该详细表示以用于调试目的。

您可以创建将从输入序列中提取键值的函数:

<#function map seq key>
    <#assign result = []>
    <#list seq as item>
        <#assign result = result + [item[key]]>
   </#list>
  <#return result>
</#function>

然后像这样使用它:

${map(container.content, "name")?join(", ")}