(This is a coldfusion question)
I've got two different Structs that may or may not contain the same data, and I want to be able to see if they do! My Structs will always contain simple values (Numbers, Strings or Booleans) because they are being created with DeserializeJSON, so hopefully this can be done easily.
I found Ben Nadel's post here, but that technique doesn't seem to working for me. Here is what I've tried so far (some cfwheels code in there):
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);
And the results of that look like:
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
so, as you'll see above, although the data inside the Structs appear to match exactly they do not pass the Equals() test.
Has anyone else done this successfully?
In Go language, you are allowed to compare two structures if they are of the same type and contain the same fields values with the help of == operator or DeeplyEqual() Method.
yes,we can compare by using thir addresses. If the 2 structures variable are initialied with calloc or they are set with 0 by memset so you can compare your 2 structures with memcmp. It is possible to use memcmp if: 1) the structs contain no floating-point fields.
Here's Ben's solution quickly adjusted to my needs, you can adjust it further (and hopefully make it pretier):
<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>
If you're using CF9 or Railo 3
ArrayContains([struct1], struct2); //case-sensitive
or
ArrayFindNoCase([struct1], struct2)); //case-insensitive, 0 if not the same.
ArrayContainsNoCase([struct1], struct2); // if you use Railo
Hidden away in Coldfusion Structures is a handy little method called hashCode(). Although keep in mind that this is undocumented.
<cfif struct1.hashCode() Eq struct2.hashCode()>
</cfif>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With