Appending to array within a loop issue

So here’s a small snippet of the runnning code:


<!--- they have at least one, so create the structure to append to the array --->
<cfset Employer = StructNew()>
<!--- WorkHistory Array --->
<cfset Application.workHistory.workHistoryDetail = ArrayNew(1)>

<cfloop from="1" to="#work_history_len#" index="i">
     <cfset Employer.employer = FORM["employer_" & i]>
     <cfset Employer.isAvailableForContact = FORM["isAvailableForContact_" & i]>
     <!--- some more key/value pairs --->

     <cfset AddIt = ArrayAppend(Application.workHistory.workHistoryDetail, Employer)>
</cfloop

So pretty basic, right? Employer is a structure that gets appended to an array at the end of each loop. What’s happening is that when there’s multiple entries all entries have the same value.

As I was writing this, I had a lightbulb go off in my head…*When I put the values from the struct into the array and then go to write the second or third values in the loop, are the values still linked to the original array?

If this is the case, what’s the solution for this? Create the Array(with a unique name) at the beginning of each loop?

are the values still linked to the original array?

Nope it copies the value of the form variable into the struct.

Make a change to the form values after, dump the array with <cfdump var=“#Application.workHistory.workHistoryDetail#” />

Are they different?

This rule applies generally to all of ColdFusion types (copying values from one to another). The only time I can recall seeing it creating a reference to another value is with CFCs.

The problem is you’re only creating 1 structure. Each time you loop you’re overwriting the values and adding that same structure to the array over and over.

If you want them to be separate you need to create a new structure on each loop. You could also use duplicate() to make a deep copy of the original. But creating a new struct is cleaner.


<cfloop from="1" to="#work_history_len#" index="i">
     <cfset Employer = structNew()>
     ....
     <cfset Employer.employer = FORM["employer_" & i]> 
</cfloop>

This rule applies generally to all of ColdFusion types (copying values from one to another). The only time I can recall seeing it creating a reference to another value is with CFCs.

No, there are others, like structures.

No, there are others, like structures.

Ah, you learn something new every day :). Just tested it and you’re right. Funny because I’ve never hit that as a problem before. Guess I’m a cleaner coder than I thought, lol

went with the duplicate method.

Thanks.

Does this mean I’m a dirty coder? Ewwwww… buzzkill. :frowning:

went with the duplicate method.

Unless you really need the existing values, you’re better off creating a new empty structure. Copying values you don’t need is just a waste of processing.

Also, be careful using duplicate(). Since it copies all values in the structure. It’s very easy to forget… and end up carrying over values you didn’t mean to…

You come from a long line of coders … and clean coding is in your blood :wink:

You might also looking using StructCopy:
http://www.cfquickdocs.com/cf8/#StructCopy

I’m not sure they should be using either. If they’re overwriting the values on each loop, there’s no reason to duplicate or copy. Just create a new (ie empty) structure, which is less processing.

You might also looking using StructCopy:

No, only use StructCopy() if you know what you’re doing. Unlike duplicate() it makes a shallow copy. That can lead to unexpected problems if the structures handle complex data and you’re not aware of that behavior.

Thus my post about “looking into it”. If they understand the ramifications and decide it’s best for them, then great.

Encouraging people to research is always good. But given the original problem in this thread, a warning about that function was definitely needed. Otherwise they could easily end up right back where they started …

I’m just a singular entity (he) rather than ‘they’, just fyi. :slight_smile:

Also I’ll try creating a new struct at the beginning of the loop instead. Thanks again for the help!

Well I didn’t know if you were a “he” or “she” … so rather than insult I went with the safer “they” :wink: But are you sure you don’t want to be “they”… it is related to the monarchy (…as in the “royal we”)

Always better to think large in this industry. You never know when things are going to grow :slight_smile: