【问题标题】:Assign key for a hash inside a hash in freemarker为freemarker中的哈希内的哈希分配密钥
【发布时间】:2015-04-24 15:31:05
【问题描述】:

我想在 freemarker 中为现有模型制作一个新模型,以使其易于使用。

我的模型是这样的:

[
    {
        "id": "1",
        "type": "TYPE_1",
        "code": "CODE_OF_TYPE_1"
    },
    {
        "id": "2",
        "type": "TYPE_1",
        "code": "ANOTHER_CODE_OF_TYPE_1"
    },
    {
        "id": "3",
        "type": "TYPE_2",
        "code": "CODE_OF_TYPE_2"
    },
    {
        "id": "4",
        "type": "TYPE_2",
        "code": "ANOTHER_CODE_OF_TYPE_2"
    }
]

我想让它变成这样:

 {
    "TYPE_1": {
        "CODE_OF_TYPE_1": "1",
        "ANOTHER_CODE_OF_TYPE_1": "2"
    },
    "TYPE_2": {
        "CODE_OF_TYPE_2": "3",
        "ANOTHER_CODE_OF_TYPE_2": "4"
    }
}

您可能知道,在 freemarker 中为哈希分配一个键有点奇怪..

我做的是这样的:

<#assign preferencesByCode = {} />

<#list preferences as preference>
    <assign preferencesByCode = preferencesByCode + {preference.type : { preference.code: preference.id } } />
</#list>

但是这样做,它只保留最后一个 id,所以我只有一种类型..

然后我尝试了这个:

<#if !(preferencesByCode[preference.type])??>
    <#assign preferencesByCode = preferencesByCode + {preference.type : { } } />
</#if>

<#assign subHash = preferencesByCode[preference.type] />
<#assign subHash = subHash + {preference.code : preference.id } />

但是 subHash 没有作为引用保存,所以任何东西都被分配给类型..

有什么想法吗?

【问题讨论】:

  • 首先,您真的必须在模板中执行此操作吗? FTL 是关于基于某些数据打印文本,而不是关于将集合/映射转换为其他集合/映射。 (按照设计,FTL 甚至没有可修改的集合/映射。)在 Java 或 Groovy 等中执行此操作,但不要在模板中执行此操作,因为它会很丑。
  • 您认为我提出的解决方案如何?有什么问题,或者只是不再感兴趣?

标签: hash freemarker


【解决方案1】:

虽然我同意 @ddekany 的评论,但这里有一个解决您问题的方法。

<#function filterList list type>
  <#local result={}>
  <#list list as preference>
    <#if preference.type == type>
      <#local result=result + {
        preference.code: preference.id
      }>
    </#if>
  </#list>
  <#return result>
</#function>

<#function convertList list>
  <#local result={}>
  <#list list as preference>
    <#if !result[preference.type]??>
      <#local result=result + { preference.type: filterList(list, preference.type) }>
    </#if>
  </#list>
  <#return result>
</#function>

<#assign transformedModel=convertList(model)>

【讨论】:

  • 我没想到!太棒了。当然,您可能知道,我决定用 Java 解决它,以便按照我的意愿传递模型。反正这就是我当年想要的!
  • 感谢您返回并接受答案,尽管您已经以不同的方式解决了问题!
【解决方案2】:

一个 freemarker 函数从某个 path 中的 root 对象返回最后一个哈希值

<#function deepHash obj path>
    <#assign hashes = path?split(".")>
    <#assign value = obj/>
    <#list hashes as hash>
        <#assign value = value[hash]!/>
    </#list>
    <#if value?is_boolean>
        <#return value?c>
    <#else>
        <#return value>
    </#if>
</#function>

例子:如果一个对象是

item 
    {
    "some": 
            {
        "thing": 
            {
                "deep": "Gotta",
            }
        }
    }


<#assign value = deepHash(item, "some.thing.deep") />
${value}

将显示:

Gotta

【讨论】:

    猜你喜欢
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-01
    • 1970-01-01
    相关资源
    最近更新 更多