对嵌套对象使用structKeyExists

问题描述 投票:4回答:3

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

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

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

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

coldfusion struct
3个回答
2
投票

isDefined()可能会返回误导性结果。它不像structKeyExists()那么准确。除非你在流行音乐中重复数千次这个代码,否则你不会注意到任何性能差异。他们都表现得很好。但是如果密钥不存在,那么您可能会注意到差异(同样,只有数千次迭代)。如果在第一次传递时找不到它,isDefined()将遍历各种可用范围。即使你传递了一个变量,看起来像是指定了你要检查的范围。 structKeyExists()在查找该键的位置非常明确。如果找不到,它将停止并返回FALSE。看起来你可能正在做不必要的工作,但它会返回更准确的结果。阅读代码可以让您对所需内容有一个很好的了解,因此您不必担心它不干净。

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


5
投票

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

ColdFusion 9 CFML Reference (PDF)


4
投票

这是一个同样的问题(虽然更简洁地说),这是一个早期问题的核心:

How to dynamically loop through an array of structures

我会提供相同的答案。

How to dynamically loop through an array of structures

要重复必要部分,以下功能应该做你想要的:

 <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>
© www.soinside.com 2019 - 2024. All rights reserved.