Copy link to clipboard
Copied
I can use arrayMax to get the max value for a small array, but I need to get which index the max value is located. That will determine which page the user goes to next. Here is my code:
array:
<cfset arrAverages[1]="#qryFairness.fairness#"/>
<cfset arrAverages[2]="#qryHonesty.honesty#"/>
<cfset arrAverages[3]="#qryCompassion.compassion#"/>
<cfset arrAverages[4]="#qrySelfControl.SelfControl#"/>
<cfset arrAverages[5]="#qryMoralConcern.MoralConcern#"/>
These values are gathered from querying values stored in a table.
I can get the max value in the array easily by:
<cfdump var="#arrayMax(arrAverages)#">
What I can't figure out is how to get the row in this array where that max value is located. It seems like it would be so simple, but nothing I have tried has worked.
Thanks,
Richard
Copy link to clipboard
Copied
For CF9 and above you can use ArrayFind/FindNoCase. Otherwise just loop through the array, and cfbreak when you find the matching value.
Copy link to clipboard
Copied
Or convert it to a list and use ListFind. But what if there are two matching records?
Copy link to clipboard
Copied
Dan, you have brought up a very interesting point. If arrayMax would give one of the max values if a tie occurs, that would be fine for this project as well. But I'll have to test that out. I did play with the list thing, but I couldn't get it to work that way either. I'm also going to see now if I can do this in the db and just use the max value I get there on my page.
Copy link to clipboard
Copied
If arrayMax would
give one of the max values if a tie occurs
ArrayMax always returns a single value. The position of the maximum value within an array is a different story.
What is your real goal here?
Copy link to clipboard
Copied
So here's the whole story/goal:
I have a survey (one of several for this project) in which the questions are grouped and scored (just on backend - users never know). The highest average group determines which page the user is sent to next. So I'm submitting the data to the db, querying the averages for each trait, now I need to get the max average to determine which page they go to next. There are 5 groups/averages. I can put these in an array or a struct but haven't yet been able to easily pull the highest GROUP out (which would be the POSITION in the array). I can pull the highest average out, but I need the position (or group) where that max occurs. It seems like it would be such an easy thing, but I'm stuck. I know I risk overlapping entries (or querying the wrong entry) by doing this after the data is submitted into the db, but I think that risk is very small and I don't know how to better do these calculations until data is in a table.
As you can see, I'm not an expert user. I'm running CF8....sounds like I could use "arrayFind" if using CF9 and all would work, but that's not an option at this time.
Copy link to clipboard
Copied
These functions will help you find the first position of the highest value in the array.
ArrayMax()
ArraytoList()
ListFind().
You can use them in separate commands or nest them in one command.
Google will lead you to sample code. The search string is "Coldfusion function name".
Copy link to clipboard
Copied
I need the position (or group) where that max occurs.
So the "group" identifier is the array index?
I'm running CF8
Then you cannot use arrayFind. Since you already have the maximum value you can use a from/to loop to examine each element in the array by position number.
<cfset maxValue = arrayMax(yourArray)>
<cfset positionOfMaxValue = -1>
<!--- found the maximum value --->
<cfloop from="1" to="#arrayLen(yourArray)#" index="position">
... ( examine current value )...
</cfloop>
Within the loop, compare the current value to the maximum value. If they are equal, just return that position number and exit the loop.
....
<!--- found the maximum value --->
<cfif yourArray[position] eq maxValue>
<cfset positionOfMaxValue = position>
<cfbreak>
</cfif>
....
As mentioned, this approach uses the first match it finds. If that is not desirable, you will need to adapt the code to suit your needs.
Copy link to clipboard
Copied
rking1966 wrote:
I can use arrayMax to get the max value for a small array, but I need to get which index the max value is located. That will determine which page the user goes to next. Here is my code:
array:
<cfset arrAverages[1]="#qryFairness.fairness#"/>
<cfset arrAverages[2]="#qryHonesty.honesty#"/>
<cfset arrAverages[3]="#qryCompassion.compassion#"/>
<cfset arrAverages[4]="#qrySelfControl.SelfControl#"/>
<cfset arrAverages[5]="#qryMoralConcern.MoralConcern#"/>
These values are gathered from querying values stored in a table.
I can get the max value in the array easily by:
<cfdump var="#arrayMax(arrAverages)#">
What I can't figure out is how to get the row in this array where that max value is located. It seems like it would be so simple, but nothing I have tried has worked.
You can find it in one line of code! Here is an example:
<cfset testArr[1]=-183>
<cfset testArr[2]=79>
<cfset testArr[3]=6>
Max.: <cfoutput>#arraymax(testArr)#</cfoutput><br>
Index of max.: <cfoutput>#arrayfindNocase(testArr, arraymax(testArr))#</cfoutput>
Copy link to clipboard
Copied
arrayfindNocase
Unfortunately they are using CF8.
Copy link to clipboard
Copied
You can leverage the fact that a CF array is a Java Vector, so you oculd use indexOf().
http://docs.oracle.com/javase/6/docs/api/java/util/Vector.html
This is not strictly supported, but realistically, CF is not going to reimplement arrays as anything else in the foreseeable future.
--
Adam
Copy link to clipboard
Copied
If you do use the underlying java object, be sure to read the api. There are subtle differences that people often overlook ... Unlike most CF array functions, indexOf() is both case and data type sensitive - and of course indexes are zero based.
This is not strictly supported, but realistically, CF is not going to
reimplement arrays as anything else in the foreseeable future.
Probably not, but generally it is still safer to code to the interface ie java.util.List rather than the implementation unless there is compelling reason to do otherwise.
Message was edited by: -==cfSearching==-
Copy link to clipboard
Copied
-==cfSearching==- wrote:
arrayfindNocase
Unfortunately they are using CF8.
I've just seen the fine print. Oh, well, here's yet another one-liner
Index of max.: <cfoutput>#listfindNocase(arrayToList(arrAverages), arraymax(arrAverages))#</cfoutput>
Copy link to clipboard
Copied
Yep, if the values are numeric, there are several different ways to slice it. Since he seemed a little unfamiliar with arrays, I suggested the long hand approach to dispel some of the mystery
-Leigh