Skip to main content
May 19, 2009
Answered

Array Question

  • May 19, 2009
  • 3 replies
  • 985 views

Hello,

Can someone figure this out? When i try to search for "27" it doesn't work, but if i try to search for "15" it seems to work. I'm breaking my head for hours trying to figure out why this isn't working.

What i'm trying to accomplish is if i do a search for "27" it takes that position in the array, then grabs that same position in the second array "arrayt[2][4]" and gives me the value, i know its possible to do something like this in perl with hashes but not sure how i can do this in coldfusion. I'm not sure if there is a better way to do this, but this is the only way i could figure out.


<cfset arrayt = ArrayNew(2)>

<cfset arrayt[1][1] = "15">
<cfset arrayt[1][2] = "19">
<cfset arrayt[1][3] = "01">
<cfset arrayt[1][4] = "27">

<cfset arrayt[2][1] = "111">
<cfset arrayt[2][2] = "112">
<cfset arrayt[2][3] = "113">
<cfset arrayt[2][4] = "114">

<cfset amount = ArrayLen(arrayt)>

<!---
Search a multidimensional array for a value.

@9397041 arrayToSearch      Array to search. (Required)
@9397041 valueToFind      Value to find. (Required)
@9397041 dimensionToSearch      Dimension to search. (Required)
@Return Returns a number.
@7111211 Grant Szabo (grant@quagmire.com)
@version 1, September 23, 2004
--->
<cffunction name="ArrayFindByDimension" access="public" returntype="numeric" output="false">
    <cfargument name="arrayToSearch" type="array" required="Yes">
    <cfargument name="valueToFind" type="string" required="Yes">
    <cfargument name="dimensionToSearch" type="numeric" required="Yes">
    <cfscript>
        var ii = 1;
       
        //loop through the array, looking for the value
        for(; ii LTE arrayLen(arguments.arrayToSearch); ii = ii + 1){
            //if this is the value, return the index
            if(NOT compareNoCase(arguments.arrayToSearch[ii][arguments.dimensionToSearch], arguments.valueToFind))
                return ii;
        }
        //if we've gotten this far, it means the value was not found, so return 0
        return 0;
    </cfscript>
</cffunction>

<cfoutput>
#ArrayLen(arrayt[1])#
<cfscript>
writeOutput(arrayFindByDimension(arrayt,"27",1) & "<br>");           
</cfscript>
</cfoutput>

    This topic has been closed for replies.
    Correct answer Uddaraju Ramesh

    Your code needs the following changes.

    Your Code :   for(; ii LTE arrayLen(arguments.arrayToSearch); ii = ii + 1){

    Changed Code :  for(; ii LTE arrayLen(arguments.arrayToSearch[arguments.dimensionToSearch]); ii = ii + 1){

    Comment : arrayLen gives only diemention. So you have to use arraydimention along with array to get total number of elements of an array dimention.

    Your Code :    if(NOT compareNoCase(arguments.arrayToSearch[ii][arguments.dimensionToSearch], arguments.valueToFind))       

    Changed Code :   if(NOT compareNoCase(arguments.arrayToSearch[arguments.dimensionToSearch][ii], arguments.valueToFind))

    3 replies

    Inspiring
    May 20, 2009

    ColdFusion isn't Perl, but its structs are, effectively, "a hash."  Therefore, it seems to me that instead of "looking for," say, "27," you should use a hash struct to determine if the value is there.  Obviously, you can do both:  the data value in the hash struct could be the [X,Y] dimension in the array where that particular value can be found.

    AFAIK, structs can be multi-dimensional so that (Holy REXX, Batman!) you could find yourself querying, say, mystructure.27.X and mystructure.27.Y...

    Uddaraju RameshCorrect answer
    New Participant
    May 20, 2009

    Your code needs the following changes.

    Your Code :   for(; ii LTE arrayLen(arguments.arrayToSearch); ii = ii + 1){

    Changed Code :  for(; ii LTE arrayLen(arguments.arrayToSearch[arguments.dimensionToSearch]); ii = ii + 1){

    Comment : arrayLen gives only diemention. So you have to use arraydimention along with array to get total number of elements of an array dimention.

    Your Code :    if(NOT compareNoCase(arguments.arrayToSearch[ii][arguments.dimensionToSearch], arguments.valueToFind))       

    Changed Code :   if(NOT compareNoCase(arguments.arrayToSearch[arguments.dimensionToSearch][ii], arguments.valueToFind))

    May 20, 2009

    Wow Uddaraju Ramesh thank you very much for your response, that was exactly what i was looking for, it worked liked a champ.

    I just have one more question, Lets say i had the following array

    <cfset arrayt = ArrayNew(2)>

    <cfset arrayt[1][1] = "15">
    <cfset arrayt[1][2] = "19">
    <cfset arrayt[1][3] = "1">
    <cfset arrayt[1][4] = "27">
    <cfset arrayt[1][5] = "1">
    <cfset arrayt[1][6] = "22">
    <cfset arrayt[1][7] = "27">

    <cfset arrayt[2][1] = "111">
    <cfset arrayt[2][2] = "112">
    <cfset arrayt[2][3] = "113">
    <cfset arrayt[2][4] = "114">
    <cfset arrayt[2][5] = "115">
    <cfset arrayt[2][6] = "116">
    <cfset arrayt[2][7] = "117">

    <cfoutput>
    #ArrayLen(arrayt[1])#
    <cfscript>
    writeOutput(arrayFindByDimension(arrayt,"27",1) & "<br>");           
    </cfscript>
    </cfoutput>

    Now since there are 2 of the same values, how would i be able to grab both instances? Or is that even possible?

    New Participant
    May 28, 2009

    See the following code for your question. As we have to return all occurences of a particular value ( in your case that is 27 ) in the list
    I modified the code to return the locations as a list.

    <cfset arrayt = ArrayNew(2)>


    <cfset arrayt[1][1] = "15">
    <cfset arrayt[1][2] = "19">
    <cfset arrayt[1][3] = "1">
    <cfset arrayt[1][4] = "27">
    <cfset arrayt[1][5] = "1">
    <cfset arrayt[1][6] = "22">
    <cfset arrayt[1][7] = "27">
     
    <cfset arrayt[2][1] = "111">
    <cfset arrayt[2][2] = "112">
    <cfset arrayt[2][3] = "113">
    <cfset arrayt[2][4] = "114">
    <cfset arrayt[2][5] = "115">
    <cfset arrayt[2][6] = "116">
    <cfset arrayt[2][7] = "117">
     

    <cfset amount = ArrayLen(arrayt)>


    <cffunction name="ArrayFindByDimension" access="public"  output="false">
         <cfargument name="arrayToSearch" type="array" required="Yes">
         <cfargument name="valueToFind" type="string" required="Yes">
         <cfargument name="dimensionToSearch" type="numeric" required="Yes">
         <cfset lst = "">
         <cfset ii = 1>
         <cfscript>
                  
             //loop through the array, looking for the value
             for(; ii LTE arrayLen(arguments.arrayToSearch[arguments.dimensionToSearch]); ii = ii + 1){
                 //if this is the value, return the index
                 if(NOT compareNoCase(arguments.arrayToSearch[arguments.dimensionToSearch][ii], arguments.valueToFind))
                     lst = lst & ii & ",";
             }
             //if we've gotten this far, it means the value was not found, so return 0
             return lst;
         </cfscript>
    </cffunction>

    <cfoutput>
    <!---#ArrayLen(arrayt[1])#--->
    Found the given number in the following locations.<br>
    <cfscript>
    writeOutput(arrayFindByDimension(arrayt,"27",1) & "<br>");          
    </cfscript>
    </cfoutput>

    ilssac
    Inspiring
    May 19, 2009

    Your function call "arrayFindByDimension(arrayt,"27",1)" combined with the "dimensionToSearch" property of your function means that this logic will only search the first element of the second deminsion of all the elements in the first dimension of your array.  I.E. the only values that could be matched would be arrayt[1][1] with a value of "15" and arrayt[2][1] with a value of "111".

    I think what you want to do is loop over all the second diminsion elements of the first element in the first dimension.  So your comparison would be something like compareNoCase(arguments.arrayToSearch[arguments.dimensionToSearch][ii], arguments.valueToFind),  This might require a close look at your looping logic to make sure you are looping over the correct diminsion.