Coldfusion counting based on patterns matching

Viewed 64

I am reading numbers off a database and create a 4 digits patterns such as:

1, 2, 2, 1
0, 2, 2, 2
4, 0, 2, 0
1, 2, 2, 1
2, 1, 1, 2

Each digit can only be from 0-6. The second step is where my problem is. I need to tally each pattern. For example, pattern 1,2,2,1 has a tally of 2 because it appears twice and the other patterns appear only once each.

At the end output, I need to be able to display each unique pattern with the count such as:

1, 2, 2, 1 - 2
0, 2, 2, 2 - 1
4, 0, 2, 0 - 1
2, 1, 1, 2 - 1

I was thinking of using a 2-dimensional array. Where

combinations[1][1]="1, 2, 2, 1" (the pattern)
combinations[1][2]=2 (the count)
combinations[2][1]="0, 2, 2, 2"
combinations[2][2]=1
etc.

How can I actually create the array dynamically while matching the pattern? i.e. if the pattern is not yet found add to the array. If it is found, add to the count. I have tried this:

<cfloop index="i" from="1" to="#ArrayLen(combinations)#">
    <cfif not arrayFind(combinations[i][1],"#patterns#")>
        <cfset arrayAppend(combinations,["#patterns#",1]) >
    <cfelse>
        <cfset combinations[i][2] = combinations[i][2] + 1>
    </cfif>
</cfloop>   

But I am getting the error on the ArrayFind:

Object of type class java.lang.String cannot be used as an array 

Any help is appreciated. Thank you in advance.

2 Answers

Solved my own question. Looks like I used the wrong function. This works:

<cfloop index="i" from="1" to="#ArrayLen(combinations)#">
    <cfif Find(combinations[i][1],"#patterns#")>
        <cfset combinations[i][2] = combinations[i][2] + 1>
        <cfset found = 1>
    </cfif>
</cfloop>
<cfif not found>
    <cfset arrayAppend(combinations,["#patterns#",1]) >
</cfif>

Instead of using a 2-dimensional array, you could also use a structure instead, in which the keys are the patterns and the values the counts. That naturally avoids duplicates because the keys of a structure can only exist once.

The code for creating the structure would look something like this:

<cfset combinations = {}>
<cfloop query="#dbresults#">
  <cfif not structKeyExists(combinations, dbresults.pattern)>
    <cfset combinations[dbresults.pattern] = 1>
  <cfelse>
    <cfset combinations[dbresults.pattern]++>
  </cfif>
</cfloop>

In the end you just have to loop over the structure to output the counts:

<cfloop collection="#combinations#" item="pattern">
  <cfoutput><p>#pattern# - #combinations[pattern]#</p></cfoutput>
</cfloop>
Related