4

我有一个像这样的嵌套结构struct1.struct2.foo。我想检查是否foo存在。但是,struct2也不保证存在。我讨厌使用isDefined(),但我也认为调用structKeyExists()两次很浪费(例如,if (structKeyExists(struct, 'struct2') && structKeyExists(struct.struct2, 'foo')) {}

我考虑过使用structFindKey(),但如果存在,我不想遇到问题struct1.foo

有没有更好的方法来实现这一点?

这是与此问题类似的问题,但我不是在处理 XML 文档,因此该帖子中的大多数答案对我不起作用。

4

3 回答 3

4

使用没有错isDefined("struct1.struct2.foo")。它并没有你想象的那么慢。从范围开始,如果你想让它更快一点,比如"variables.struct1.struct2.foo"

ColdFusion 9 CFML 参考 (PDF)

于 2013-02-19T23:13:01.597 回答
4

这是前面一个问题的核心问题(虽然更简洁):

如何动态循环遍历结构数组

我会提供同样的答案。

如何动态循环遍历结构数组

要重复基本部分,以下功能应该可以满足您的需求:

 <cffunction name="StructGetByKeyList">
      <cfargument name="struct">
      <cfargument name="key">

      <cfif StructKeyExists(struct,ListFirst(key,"."))>
           <cfif ListLen(key,".") GT 1>
                <cfreturn StructGetByKeyList(struct[ListFirst(key,".")],ListRest(key,"."))>
           <cfelse>
                <cfreturn struct[key]>
           </cfif>
      <cfelse>
           <cfreturn "">
      </cfif>
 </cffunction>

然后你可以只调用 StructGetByKeyList(struct1,"struct2.foo") ,如果它存在,它会返回键的字符串,如果不存在,它会返回一个空字符串。

要改为返回布尔值,请使用以下命令:

<cffunction name="StructNestedKeyExists">
    <cfargument name="struct">
    <cfargument name="key">

    <cfif StructKeyExists(struct,ListFirst(key,"."))>
        <cfif ListLen(key,".") GT 1>
            <cfreturn StructNestedKeyExists(struct[ListFirst(key,".")],ListRest(key,"."))>
        <cfelse>
            <cfreturn true>
        </cfif>
    <cfelse>
        <cfreturn false>
    </cfif>
</cffunction>
于 2013-02-20T16:59:20.220 回答
2

isDefined() 可能会返回误导性结果。它不如 structKeyExists() 准确。除非您在弹出时对这段代码进行数千次迭代,否则您不会注意到任何性能差异。他们俩的表现都不错。但是,如果密钥不存在,那么您可能会注意到差异(同样,只有数千次迭代)。isDefined() 将遍历各种可用范围,如果它在第一遍找不到它。即使您向它传递了一个看起来像是指定了您要检查的范围的变量。structKeyExists() 在查找该键的位置非常明确。如果没有找到,它将停止并返回 FALSE。看起来您正在做不必要的工作,但它返回的结果要准确得多。

彼得的建议非常好。看看那个链接。

于 2013-02-20T00:43:47.093 回答