• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

find Index for max value of array

New Here ,
Dec 05, 2011 Dec 05, 2011

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

TOPICS
Advanced techniques

Views

2.5K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 05, 2011 Dec 05, 2011

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 05, 2011 Dec 05, 2011

Copy link to clipboard

Copied

Or convert it to a list and use ListFind.  But what if there are two matching records?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 06, 2011 Dec 06, 2011

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 06, 2011 Dec 06, 2011

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 06, 2011 Dec 06, 2011

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 06, 2011 Dec 06, 2011

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". 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 06, 2011 Dec 06, 2011

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 07, 2011 Dec 07, 2011

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>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 07, 2011 Dec 07, 2011

Copy link to clipboard

Copied

arrayfindNocase

Unfortunately they are using CF8.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 07, 2011 Dec 07, 2011

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 07, 2011 Dec 07, 2011

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==-

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 07, 2011 Dec 07, 2011

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>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 07, 2011 Dec 07, 2011

Copy link to clipboard

Copied

LATEST

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation