java - 如何在两个结构上执行 "deep compare"或 "diff"?

标签 java coldfusion railo cfwheels cfml

(这是一道冷聚变题)

我有两个不同的结构,它们可能包含也可能不包含相同的数据,我想看看它们是否包含相同的数据!我的结构将始终包含简单值(数字、字符串或 boolean 值),因为它们是使用 DeserializeJSON 创建的,所以希望这可以轻松完成。

我找到了 Ben Nadel 的帖子 here ,但该技术似乎对我不起作用。到目前为止,这是我尝试过的方法(其中包含一些 cfwheels 代码):

itemA = DeSerializeJSON(model("itemsnapshot").findByKey(4).json);
itemB = DeSerializeJSON(model("itemsnapshot").findByKey(5).json);

StructDelete(itemA,"updatedAt");
StructDelete(itemB,"updatedAt");
StructDelete(itemA,"createdAt");
StructDelete(itemB,"createdAt");

writedump(itemA);
writedump(itemB);

out = itemA.Equals(itemB);
writedump(out);

结果如下:

Struct
code string C112
companyid number 1
cost number 5000
deletedAt string 
description string Nightstand
id number 70634
itemtypeid string 13
projectid number 8
unittypeid string

Struct
code string C112
companyid number 1
cost number 5000
deletedAt string 
description string Nightstand
id number 70634
itemtypeid string 13
projectid number 8
unittypeid string 

boolean false

因此,正如您将在上面看到的,尽管 Structs 中的数据看起来完全匹配,但它们没有通过 Equals() 测试。

有没有人成功地做到了这一点?

最佳答案

这是根据我的需要快速调整的 Ben 解决方案,您可以进一步调整它(并希望让它更漂亮):

<cffunction name="DiffStructs" hint="Compute the differences between two structures" access="public" output="true" returntype="array" >
        <cfargument name="First" type="struct" required="true" />
        <cfargument name="Second" type="struct" required="true" />
        <cfargument name="ignoreMissing" type="boolean" required="false" default="false" />
        <cfargument name="ignoreFirstEmptyString" type="boolean" required="false" default="false" />
        <cfargument name="ignoreSecondEmptyString" type="boolean" required="false" default="false" />

        <cfset var Result = arrayNew(1) >
        <cfset var Keys = structNew() >
        <cfset var KeyName = "" >
        <cfset var obj = "" >
        <cfset var firstOk = true >
        <cfset var secondOk = true >

        <cfloop collection="#Arguments.First#" item="KeyName">
                <cfset Keys[KeyName]=1>
        </cfloop>
        <cfloop collection="#Arguments.Second#" item="KeyName">
                <cfset Keys[KeyName]=1>
        </cfloop>
        <cfloop collection="#Keys#" item="KeyName">
            <cfif NOT StructKeyExists(Arguments.First, KeyName)  >
                    <cfif NOT arguments.ignoreMissing>
                        <cfif structFind(Arguments.Second, KeyName) neq "">
                            <cfif arguments.ignoreSecondEmptyString>
                                <cfset obj = {  key = KeyName
                                                ,old = ""
                                                ,new = structFind(Arguments.Second, KeyName) } >
                                <cfset arrayAppend(Result, obj )>
                            </cfif>
                        </cfif>
                    </cfif>

            <cfelseif NOT StructKeyExists(Arguments.Second, KeyName)>
                    <cfif NOT arguments.ignoreMissing>
                        <cfif structFind(Arguments.First, KeyName) neq "">
                            <cfif arguments.ignoreFirstEmptyString >
                                <cfset obj = {  key = KeyName
                                                ,old = structFind(Arguments.First, KeyName) 
                                                ,new = "" } >
                                <cfset arrayAppend(Result, obj )>
                            </cfif>
                        </cfif>
                    </cfif>

            <cfelseif Arguments.First[KeyName] NEQ Arguments.Second[KeyName] >

                <cfset firstOk = true >
                <cfset secondOk = true >

                <cfif structFind(Arguments.Second, KeyName) eq "">
                    <cfif arguments.ignoreSecondEmptyString>
                        <cfset firstOk = false >
                    </cfif>
                </cfif>

                <cfif structFind(Arguments.First, KeyName) eq "">
                    <cfif arguments.ignoreFirstEmptyString>
                        <cfset secondOk = false >
                    </cfif>
                </cfif>

                <cfif firstOk AND secondOk >
                    <cfset obj = {  key = KeyName
                                    ,old = structFind(Arguments.First, KeyName) 
                                    ,new = structFind(Arguments.Second, KeyName) } >
                    <cfset arrayAppend(Result, obj )>
                </cfif>
            </cfif>

        </cfloop>

        <cfreturn Result>
    </cffunction>

关于java - 如何在两个结构上执行 "deep compare"或 "diff"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3147124/

相关文章:

java - 从日志中获取异常

mysql - 循环 ColdFusion 查询并递增计数器

java - 如何在 Hibernate 的 XML 文件中声明一对多映射?

java - 如何将文件对象类型转换为 InputStream

java - 在防火墙后使用 JMX 连接到远程 JBoss

function - 在coldfusion的文件路径中找到 `/`的最后一次出现

javascript - 在 Coldfusion 中捕获 'Last Record' for IE javascript bug

coldfusion - 如何在不重新启动服务器的情况下清除 Coldfusion 查询缓存?

railo - <cfinclude> 和相对位置

coldfusion - 如何在 cfscript 标记内执行 cfdump?