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