Looping Through an Array Using Coldfusion

I have a shopping cart array, which has a variable to tell me if the product is an accessory or not, this will be either yes or no. I need to loop through the cart and find out the following:

  • If the cart contains accessories only; do whatever.
  • If the cart is products only; do whatever.
  • If the cart has products and accessories; do whatever.

I have been trying this:

<cfloop index="i" from="1" to="#arrayLen(session.mycart)#">
  <cfif session.mycart[i].accs EQ "yes">
    <cfset accPresent = "yes">
  </cfif>
  <cfif session.mycart[i].accs EQ "no">
    <cfset prodpresent = "yes">
  </cfif>
</cfloop>

<cfif accPresent EQ "yes" and prodPresent EQ "no">
  <cfset  bothPresent EQ "yes">
</cfif>

This falls down as accPresent is not found, this i think is due to the fact the loop goes through one at a time and the accs is not equal to yes once it find a non accessory product. What's the best way to achieve what I'm trying to do?

4 Answers

Do this

<cfset accPresent = "no" />
<cfset prodPresent = "no" />
<cfloop index="i" from="1" to="#arrayLen(session.mycart)#">
    <cfif session.mycart[i].accs EQ "yes">
        <cfset accPresent = "yes">
    </cfif>
    <cfif session.mycart[i].accs EQ "no">
        <cfset prodpresent = "yes">
    </cfif>
</cfloop>

<cfif accPresent EQ "yes" and prodPresent EQ "no">
    <cfset  bothPresent EQ "yes">
</cfif>
2

Jason,

Your 3rd statement assumes that AccPresent and ProdPresent will both exist. Did you create them first and give them default values? Try this:

<cfparam name="accPresent" default="no"/>
<cfparam name="prodPresent" default="no"/>
<cfloop index="i" from="1" to="#arrayLen(session.mycart)#">
<cfif session.mycart[i].accs EQ "yes">
<cfset accPresent = "yes">
</cfif>
<cfif session.mycart[i].accs EQ "no">
<cfset prodpresent = "yes">
</cfif>
</cfloop>    
<cfif accPresent EQ "yes" and prodPresent EQ "no">
<cfset  bothPresent EQ "yes">
</cfif>

This assumes of course that each of these should be set to "no" by default.

4

In versions of ColdFusion 8 and higher, a <cfloop> can use an array directly

<cfloop index="i" array="#session.mycart#">
  <cfif i.accs EQ "yes">
    <cfset accPresent = "yes">
  </cfif>
  <cfif i.accs EQ "no">
    <cfset prodpresent = "yes">
  </cfif>
</cfloop>

<cfif accPresent EQ "yes" and prodPresent EQ "no">
  <cfset  bothPresent EQ "yes">
</cfif>

Note: That i refers to the struct containing the data, not position of the data

In CF 10 (or Railo 4), this can be done more elegantly using cfscript and the Underscore.cfc library:

_ = new Underscore();

myCart = duplicate(session.myCart);

accPresent = _.any(myCart, function(val) {
    return val.accs;
});

prodPresent = _.any(myCart, function(val) {
    return !val.accs;
});

bothPresent = accPresent && prodPresent;

The great thing about _.find() is that it stops as soon as the iterator function returns true, so you don't have to iterate over every single element in the array.

Note: Using duplcate() is recommended when accessing shared-scope variables in order to prevent deadlocks.

(Disclaimer: I wrote Underscore.cfc)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.

Share this article
Twitter Facebook Pinterest