Link to home
Start Free TrialLog in
Avatar of mjacobs2929
mjacobs2929

asked on

Accessing a structure of array...

How can I best access the innermost array text in a structure like the one below? It is a structure which contains an array, which contains another structure, which contains another array. A sample loop would be welcome:

struct
Errata
  array
  1
    struct
    Text
       array
       1 Guests wanting to book a walking tour
       2 must speak to their representative
       3 locally. For any guests staying 7 nights
       4 or less will not be able to take part
       5 in the Tuesday tour. Picnics are
       6 available and bookable locally at an
       7 additional charge.

Many thanks,
MJ
Avatar of Dain_Anderson
Dain_Anderson

This almost looks like an array that has a structure, which then has an array. To produce (at least what I *kind of* think you've got) it:

<CFSET Errata = ArrayNew(1)>
<CFSET Errata[1] = StructNew()>
<CFSET Errata[1].Text = ArrayNew(1)>
<CFSET Errata[1].Text[1] = "Guests wanting to book a walking tour">
<CFSET Errata[1].Text[2] = "must speak to their representative">
<CFSET Errata[1].Text[3] = "locally. For any guests staying 7 nights">
<CFSET Errata[1].Text[4] = "or less will not be able to take part">
<CFSET Errata[1].Text[5] = "in the Tuesday tour. Picnics are">
<CFSET Errata[1].Text[6] = "available and bookable locally at an">
<CFSET Errata[1].Text[7] = "additional charge.">

If this is the case, to access the innermost array, you can use the syntax:

<CFOUTPUT>
<CFLOOP FROM="1" TO="#ArrayLen(Errata[1].Text)#" INDEX="i">
    #Errata[1].Text[i]#<BR>
</CFLOOP>
</CFOUTPUT>

To loop through the entire things, you could wrap that within another loop:

<CFOUTPUT>
<CFLOOP FROM="1" TO="#ArrayLen(Errata)#" INDEX="j">
      <CFLOOP FROM="1" TO="#ArrayLen(Errata[j].Text)#" INDEX="i">
          #Errata[1].Text[i]#<BR>
      </CFLOOP>
</CFLOOP>
</CFOUTPUT>

There are a lot of other was to play with arrays and structs, but hopefully this gets you started.

-Dain
ASKER CERTIFIED SOLUTION
Avatar of Dain_Anderson
Dain_Anderson

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Main trouble here is that if you want to automatically get to the deepest point of the array/struct structure, the fieldname of the structs inside must be known. For example, if thye fieldname was consistently 'errata', and there was consistently only one element in the array, it would be something like this:

<cfset mainStruct = StructNew()>
<cfset mainStruct.errata = ArrayNew(1)>
<cfset mainStruct.errata[1] = StructNew()>
<cfset mainStruct.errata[1].errata = ArrayNew(1)>
<cfset mainStruct.errata[1].errata[1] = 'Blah!'>

<cfset curStruct = mainStruct>
<cfloop condition="#isArray(curStruct['errata'])#">
<cfif not isStruct(curStruct['errata'][1])>
  <cfset successArr = curStruct['errata']>
  <cfbreak>
<cfelse>
  <cfset curStruct = curStruct['errata'][1]>
</cfif>
</cfloop>

<cfdump var="#successArr#" label="the right one">


Hope this helps

-Umbrae
Bah. I realized I just overcomplicated things by assuming you meant you wanted to find the innermost array regardless of depth. My apologies.
Avatar of mjacobs2929

ASKER

Thanks Dain,

This seems to work (sorry, forgot to mention that 'Text' is always the innermost array):

<cfoutput>
 <cfloop from="1" to="#ArrayLen(StructKeyArray(ResultfromcfcGemini))#" index="i">
  <cfloop from="1" to="#ArrayLen(ResultfromcfcGemini.Errata)#" index="j">
       <cfloop from="1" TO="#ArrayLen(ResultfromcfcGemini.Errata[j].Text)#" index="k">
             #ResultfromcfcGemini.Errata[j].Text[k]#<br>
       </cfloop>
  </cfloop>
 </cfloop>
</cfoutput>


There can also be more than one array in 'Errata'.

Now I need to concat: #ResultfromcfcGemini.Errata[j].Text[k]#

Many thanks,
MJ
Groovy -- glad I could help!

-Dain