Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird behaviour with arrays in ColdFusion

I am facing issue with a piece of code, with slight modification I am getting different results which should not be the case.

Version 1 is giving the correct results, I am facing issue with Version 2 which is the actual code.

Version 1:

<cfset keywords = listToArray("1,2,3,4,5,6,7,8,9,10")>

<!--- Common Code Below --->
<cfoutput>#getMetadata(keywords).getName()#</cfoutput>

<cfset toBeAdded = keywords>
<cfset toBeInactivated = listToArray("1,3,4,6,8")>
<cfset toBeActivated = toBeInactivated>

<cfset toBeAdded.removeAll(toBeInactivated)>
<cfset toBeInactivated.removeAll(keywords)>
<cfset toBeActivated.retainAll(keywords)>

Version 2:

<cfset keywords = []>
<cfloop from="1" to="10" index="counter">
    <cfset arrayAppend( keywords, counter )>
</cfloop>

<!--- If I add following line here then it is working as expected and similar to version 1:  --->
<!--- <cfset keywords = listToArray(arrayToList(keywords))> --->

<!--- Common Code Below --->
<cfoutput>#getMetadata(keywords).getName()#</cfoutput>

<cfset toBeAdded = keywords>
<cfset toBeInactivated = listToArray("1,3,4,6,8")>
<cfset toBeActivated = toBeInactivated>

<cfset toBeAdded.removeAll(toBeInactivated)>
<cfset toBeInactivated.removeAll(keywords)>
<cfset toBeActivated.retainAll(keywords)>

Outputs:

enter image description hereenter image description here

Here are the gists: Version 1 and Version 2.

Any suggestions are greatly appreciated!

like image 825
Beginner Avatar asked Jun 29 '17 08:06

Beginner


1 Answers

I'm no Java guy but from what I can tell...

In Version 1: keywords contains java.lang.String values and in Version 2: keywords contains java.lang.Double values.

In Version 2: toBeInactivated contains strings values to be removed from the array of doubles.

Since those Java types do not match, they won't be removed from the collection properly. I'm guessing when CF passes the underlying object data around, it's never casted correctly. Which honestly I'd expect when everything is typeless to CF.

Adding on from the comment by @Twillen below, this works when you cast counter to a type of java.lang.String:

<cfset keywords = []>
<cfloop from="1" to="10" index="counter">
    <cfset arrayAppend( keywords, javaCast("string", counter) )>
</cfloop>


<!--- Common Code Below --->
<cfoutput>#getMetadata(keywords).getName()#</cfoutput>

<cfset toBeAdded = keywords>
<cfset toBeInactivated = listToArray("1,3,4,6,8")>
<cfset toBeActivated = toBeInactivated>

<cfset toBeAdded.removeAll(toBeInactivated)>
<cfset toBeInactivated.removeAll(keywords)>
<cfset toBeActivated.retainAll(keywords)>

<cfdump var="#toBeAdded#" label="To Be Added">
<cfdump var="#toBeInactivated#" label="To Be Inactivated">
<cfdump var="#toBeActivated#" label="To Be Activated">
like image 159
Tony Junkes Avatar answered Nov 15 '22 07:11

Tony Junkes