我有一个像struct1.struct2.foo
这样的嵌套结构。我想检查foo
是否存在。但是,struct2
也不保证存在。我不喜欢使用isDefined()
,但我也认为拨打structKeyExists()
两次是浪费的(例如,if (structKeyExists(struct, 'struct2') && structKeyExists(struct.struct2, 'foo')) {}
我考虑过使用structFindKey()
,但如果存在struct1.foo
有没有更好的方法来实现这一目标?
这是与this question类似的问题,但我没有处理XML文档,因此该帖子中的大多数答案对我都不起作用。
答案 0 :(得分:5)
使用isDefined("struct1.struct2.foo")
没有错。它并不像你想象的那么慢。如果您想让它更快一些,请从范围开始,例如"variables.struct1.struct2.foo"
答案 1 :(得分: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>
答案 2 :(得分:2)
isDefined()可能会返回误导性结果。它不像structKeyExists()那么准确。除非你在流行音乐中重复数千次这个代码,否则你不会注意到任何性能差异。他们都表现得很好。但是如果密钥不存在,那么您可能会注意到差异(同样,只有数千次迭代)。如果在第一次传递时找不到它,isDefined()将遍历各种可用范围。即使你传递了一个变量,看起来像是指定了你要检查的范围。 structKeyExists()在查找该键的位置非常明确。如果找不到,它将停止并返回FALSE。看起来你可能正在做不必要的工作,但它会返回更准确的结果。阅读代码可以让您对所需内容有一个很好的了解,因此您不必担心它不干净。
彼得的建议非常好。看看那个链接。