Skip to main content
wmkolcz
Inspiring
May 15, 2011
Question

Merging Arrays

  • May 15, 2011
  • 3 replies
  • 1327 views

I have 4 Arrays of Objects/Structures in my function that I need to merge into one Array so I can return it to my Flex app. I googled it and found a bunch of articles that talk about using the Java function addAll(), but when I tried, it returned an errors saying the function was not found. I saw other articles that talked about the old way of looping over with the Array attribute and passing in the index, but I keep getting a weird Java Boolean as an Array error. Can anyone help me figure this out?

Here is what I have:

<cfset allPets = ArrayNew(1) />
        <cfloop array="#adoptables#" index="i">
              <cfset allPets = ArrayAppend(allPets, #i#)>
        </cfloop>       
        <cfloop array="#pending#" index="i">
              <cfset allPets = ArrayAppend(allPets, #i#)>
        </cfloop>
        <cfloop array="#adopted#" index="i">
              <cfset allPets =  ArrayAppend(allPets, #i#)>
        </cfloop>
        <cfloop array="#hold#" index="i">
              <cfset allPets =  ArrayAppend(allPets, #i#)>
        </cfloop>

It is an Array of Structures if that helps. Thanks!

This topic has been closed for replies.

3 replies

Inspiring
July 15, 2011

This has come back onto my radar due to inursactive's reply.

On re-read, I spotted this:

I googled it and found a bunch of articles that talk about using the Java function addAll(), but when I tried, it returned an errors saying the function was not found

This didn't ring true to me, because I've used addAll() to concatenate CF arrays ebfore, so I looked into it.

This code works fine:

<cfscript>
    a1 = [];
    a2 = [];
    for (i=1; i <=5; i++){
        a1 = {
            number = i
        };
        a2 = {
            letter = chr(64+i)
        };
    }
    a1.addAll(a2);
    writeDump(a1);   
</cfscript>

So I'm interested to see what your code was...

--

Adam

Inspiring
July 15, 2011

Wow, that's pretty slick.  I always forget about the underlying Java classes behind the CF objects.  In case you're not familiar with this technique wmkolcz - remember that anytime you use an "undocumented" feature in CF there is a chance (though very small in this case) that an update to CF will break your functionality - say if the CF team decides to rewrite the underlying class behind the array object in CF.  Ben Nadel has an excellent article where he looks at this exact issue and builds an array append/combine custom function in CF along with an excellent discussion in the comments about the various pros/cons of the different methods:

http://www.bennadel.com/blog/2059-Appending-One-Array-To-Another-With-ArrayAppendAll-In-ColdFusion.htm

IMHO - Adam's solution will be the quickest and most reliable of all the suggestions.  I just thought you might not be aware of the implications.

Inspiring
July 15, 2011
discussion in the comments about the various pros/cons of the different methods:

Two other considerations you do not hear discussed much (though you should):

anytime you use an "undocumented" feature ... there is a chance .. that an update to CF will break your functionalityaware of the implications.

1) It is a risk. Some things are obviously more risky than others. ie ServiceFactory is more risky than using a java.lang.String. However, if you do chose to use this stuff, try and stick to using interfaces. Those are less likely to change than the underlying implementation. For example with CF arrays, do not use methods found only in  java.util.Vector such as elementAt(..). Stick the methods in java.util.List and you will better insulate yourself against changes.  Then if adobe  decides arrays should be implemented as java.util.ArrayList tomorrow,  your code will still work. At least under ACF anyway. As mentioned in the  link, you basically throw portability out the window once you start  using the java internals. So if you are even thinking about using multiple engines, it is an important consideration.

2)  A lot of java classes have nuances CF lacks. Be sure to know the classes you are using and how they differ from CF.  It is extremely easy to trip yourself up by overlooking those small differences.

  
   // resulting array might not be what you expect ...
    jArr = str.split("|");
   // jArr is not a CF array. so the append fails
    arrayAppend(jArr, "grape");

   // parameter test is not found because map is case sensitive
   // url: test.cfm?tesT=123
   getPageContext().getRequest().getParameterMap()
   map = getPageContext().getRequest().getParameterMap();
   structKeyExists(map, "test");

Inspiring
July 14, 2011

You could always use ArrayToList() to flatten your arrays, concatenate them together into one long list and then combine using ListToArray().  You may need to use a custom delimeter (e.g. |) if you think your array values might have commas.  It essentially accomplishes that same thing, but requires less lines of code and might be a little cleaner to maintain.

Of course it helps if I actually read the original post a little better.  Doh - arrays of structures.  Yeah - those don't flatten too well.  You could always accomplish the same thing with serializing/deserializing the data using WDDX or JSON.

Message was edited by: insuractive

Inspiring
May 15, 2011

Read the docs.

http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7f21.html

What does arrayAppend() return?

How does the docs say arrayAppend() should be used?

--

Adam

ilssac
Inspiring
May 16, 2011

And once you have learned what Adam is showing you don't feel to bad.

I'm ALWAYS confusing the behaviors of ArrayAppend() and ListAppend() [and the prepend versions] and mistyping which one needs to reset the variable and which one does not.