Skip to main content
New Participant
August 22, 2009
Question

Make unique array of structure

  • August 22, 2009
  • 2 replies
  • 1829 views

Hi all.

How can make array of unique elements ?

Heed to get from array -> array1

<cfset array = arrayNew(1) />
<cfset array1 = arrayNew(1) />

<cfset array[ 1 ] = { id = '1' } />
<cfset array[ 2 ] = { id = '1' } />
<cfset array[ 3 ] = { id = '1' } />
<cfset array[ 4 ] = { id = '2' } />
<cfset array[ 5 ] = { id = '3' } />
<cfset array[ 6 ] = { id = '4' } />
<cfset array[ 7 ] = { id = '4' } />
<cfset array[ 8 ] = { id = '5' } />

<cfdump var="#array#" label="Current" />

<cfset array1[ 1 ] = { id = '1' } />
<cfset array1[ 2 ] = { id = '2' } />
<cfset array1[ 3 ] = { id = '3' } />
<cfset array1[ 4 ] = { id = '4' } />
<cfset array1[ 5 ] = { id = '5' } />

<br /><br />
<cfdump var="#array1#" label="Needfull" />

    This topic has been closed for replies.

    2 replies

    Inspiring
    August 24, 2009

    There are a few 'tricks' that you can use here ...

    1. A "struct" is fundamentally an associative-array structure.  So, if you've got an "id" field of any sort, a struct can locate any "id" almost instantly.  This is much faster than searching an array (which has a hidden cost created by virtual-memory paging over a large "footprint").
    2. When you add a struct to another struct or to an array, you are actually moving a reference to the structure.  You should find that (afaik!), if the struct is present both in an array and in a struct, both of these are references to one-and-the-same memory block.
    3. Use the most-convenient data structure when building the original set of records.  This is probably going to be a "struct."  If you then need to have an array of elements sorted in a particular way, build that array last, by using a "sort" operation to arrange the records in whatever order you want.  Since you'are actually (afaik...) moving references, you're not stomping on too much RAM.

    "Sorting" is what I call an "unexpectedly fast and efficient" operation, because it's one of the most heavily-studied operations in all of data processing ... and has been since the days of Herman Hollerith.

    Inspiring
    August 22, 2009

    You would need to search the array each time you appended a structure. Then append the structure, only if did not already exist in the array. But that raises the question, is an array really the right type of object to be using in the case?  A structure, which does not allow duplicates, would seem more appropriate.

    cetverAuthor
    New Participant
    August 22, 2009

    if i wont delete elements if they first element eq second element etc.

    <cfset limit = arrayLen(array) />
    <cfloop from="#limit#" to="1" index="i" step="-1" >
        <cfloop from="1" to="#i-1#" index="j" step="1">
            <cfif array.id EQ array[j+1].id>       
                <cfset ArrayDeleteAt(array.id, j) />           
            </cfif>
        </cfloop>
    </cfloop>

    <cfdump var="#array#" label="Needfull" />

    but i get this error:

    You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members.

    help with syntax pls

    Inspiring
    August 22, 2009

    No. The easier way is to search the array _before_ elements are added, not after.  If for whatever reason you cannot do that, it would be easier to use a structure to eliminate the duplicates. Then convert it back to an array.

    <cfset keep = {} >
    <cfloop array="#array#" index="elem">
        <cfset keep[elem.id] = elem>
    </cfloop>

    <cfset finalArray = []>
    <cfloop collection="#keep#" item="key">
        <cfset arrayAppend(finalArray, keep[key]) >
    </cfloop>

    <cfdump var="#finalArray#" label="finalArray" />

    But, why are you using an array here?