I have many structures, I’m using StructFindValue() to determine if a a key occurs many times.
I get the expected array returned for “singles”, however I get an empty array for “doubles” and “triples” – this code is actually inside a different code segment, -my is a structure in itself…
If I try ANY of the lines “x= StructFindValue( y, 3, ‘all’ );” in a stand alone template – CF finds the ‘2’ and ‘3’ values just fine – I get an array with the data – but inthe above code – ONLY the values of ‘1’ return anything…
I’m confused.
UPDATE
OK, in response to the request for more information, my server details are:
Version ColdFusion 10,282462
Edition Developer
Operating System Windows XP
Java Version 1.6.0_29
OS Version 5.1
Update Level /C:/ColdFusion10/cfusion/lib/updates/chf10000002.jar
Adobe Driver Version 4.1 (Build 0001)
As you can see from the code example below, my array has a few different names, of differing repetitive nature. I want to know which values repeat a specified number of times. As stated above, the structkeyFind() works IF (and only) on the key value of 1. It doesn’t work with the key values of 2, 3 (or 4 or 5 etc, not included here for brevity).
<cfscript>
_myArry = listToArray('bob,bob,bob,joe,jane,jane,john,john,john,alex,greg');
_myStats = getDataStats( _myArry );
writeDump( _myStats );
</cfscript>
<cffunction name="getDataStats">
<cfargument name="data" required="yes" type="array" >
<cfscript>
var _hv = {};
// default some values
_hv.vals = {};
_hv.threes = false;
_hv.twos = false;
_hv.ones =false;
// loop the data put it into separate containers
for ( var i=1; i LTE arrayLen( arguments.data ); i++ ) {
switch ( lcase( arguments.data[i] ) ) {
case 'bob': // bob
if ( structKeyExists( _hv.vals, 'bob' ) ) { _hv.vals.bob = _hv.vals.bob + 1; }
else { _hv.vals.bob = 1; }
break;
case 'joe': // joe
if ( structKeyExists( _hv.vals, 'joe' ) ) { _hv.vals.joe = _hv.vals.joe + 1; }
else { _hv.vals.joe = 1; }
break;
case 'jane': // jane
if ( structKeyExists( _hv.vals, 'jane' ) ) { _hv.vals.jane = _hv.vals.jane + 1; }
else { _hv.vals.jane = 1; }
break;
case 'john': // john
if ( structKeyExists( _hv.vals, 'john' ) ) { _hv.vals.john = _hv.vals.john + 1; }
else { _hv.vals.john = 1; }
break;
case 'alex': // alex
if ( structKeyExists( _hv.vals, 'alex' ) ) { _hv.vals.alex = _hv.vals.alex + 1; }
else { _hv.vals.alex = 1; }
break;
case 'greg': // greg
if ( structKeyExists( _hv.vals, 'greg' ) ) { _hv.vals.greg = _hv.vals.greg + 1; }
else { _hv.vals.greg = 1; }
break;
}
}
// give me a return struct for testing so i can 'see' where I'm at
var _thisReturn = {
'threes' = StructFindValue( _hv.vals, 3, 'all' ),
'twos' = StructFindValue( _hv.vals, 2, 'all' ),
'ones' = StructFindValue( _hv.vals, 1, 'all' ),
'values' = arguments.data
};
</cfscript>
<cfreturn _thisReturn />
</cffunction>
In an attempt to ‘cast’ the values, I have tried each of these variations. However the results are UNCHANGED from the original.
'ones' = StructFindValue( _hv.vals, '1', 'all' ),
'twos' = StructFindValue( _hv.vals, '2', 'all' ),
'threes' = StructFindValue( _hv.vals, '3', 'all' ),
And then
'ones' = StructFindValue( _hv.vals, val( 1 ), 'all' ),
'twos' = StructFindValue( _hv.vals, val( 2 ), 'all' ),
'threes' = StructFindValue( _hv.vals, val( 3 ), 'all' ),
The issue here appears to be how CF is storing / displaying / comparing the values.
Here is a simple demonstration of the problem:
The first dump displays all values as
2except for John who is2.0However, the first two StructFindValue calls both only return
Bob,Jane.The third StructFindValue call returns
Joe,John,Alex.This basically demonstrates that CF’s StructFindValue does a very crude comparison for checking equality, and basically isn’t to be trusted when it comes to dealing with numbers.
(The issue doesn’t exist with Railo, which probably uses the exact same comparison as it would when doing an
EQtest, coercing types accordingly. Only tested on CF10,0,0,282462.)To solve your problem, it seems you may need to manually walk the struct and replicate the behaviour of StructFindValue yourself.