ArrayCount - wish list


#1

I just keep finding times when I want to use ArrayCount, a wish list item I posted years ago. I’ve always found ways to accomplish it, but it would be so useful to use such a Function to find out how many times various elements occur within an array.


#2

It should be rather easy to create a functiion using something along these lines:

extract(arraystrip(arrayfilter(theArray,theSep,|||?(import()=theText,import(),"")|||),theSep),theSep,-1)

theArray would be the array name while theText would be the element text to search for and theSep is the separator used in the array. Using the extract( function assures that if there is no such element in the array it returns a 0.


#3

Since array separators aren’t limited to a single character anymore, you could also use

arraysize(theSep+theArray+theSep,theSep+theText+theSep)-1


#4

Dave Thompson wrote an ArrayElementCount custom statement some years back - it’s currently in my collection of custom statements and functions to load when Jim gives us the knowhow with the next version. The code is posted below

I’ll look into making an Extract( function - unless you want to do it Gary?

/*
  <PROCEDUREINFO>
  <DESCRIPTION>
  The ARRAYELEMENTCOUNT statement takes an array with duplicated elements and returns a 
  deduplicated array, where each element consists of an element from the
  original array and a frequency count. The frequency count is the number 
  of times the element occurs in the original array. The original
  element and the frequency count are separated by a joiner of one or 
  more characters.
  </DESCRIPTION>
  <PARAMETER NAME=InputArray TYPE=TEXT> The original array, with all 
  the elements </PARAMETER>
  <PARAMETER NAME=OutputArray TYPE=TEXT>  A field or variable to receive 
  the deduplicated array with frequency count </PARAMETER>
  <PARAMETER NAME=Sep TYPE=TEXT> The array separator </PARAMETER>
  <PARAMETER NAME=Join TYPE=TEXT> The joiner between each element and 
  its respective frequency count </PARAMETER>
<EXAMPLES>
The statement<p>
arrayelementcount "a,b,c,a,d,b",AVariable,","," - "
<p>
will set AVariable to: <p>
"a - 2,b - 2,c - 1,d - 1"
</EXAMPLES>


<testdata></testdata>

</PROCEDUREINFO>
    */

// Submitted by David Thompson

Local x,InputArray,OutputArray,Sep,Join
InputArray=parameter(1)
if error rtnerror info("error") endif
Sep=parameter(3)[1,1]
if error rtnerror info("error") endif
Join=parameter(4)
if error rtnerror info("error") endif

ArraySort InputArray, InputArray,Sep
ArrayDeDuplicate InputArray, OutputArray,Sep
ArrayFilter OutputArray,x,Sep,arraysearch(InputArray,import(),1,Sep)
x=x+Sep+str(arraysize(InputArray,Sep)+1)
ArrayFilter OutputArray, OutputArray,Sep,import()+Join
        +str(val(array(x,seq()+1,Sep))-val(array(x,seq(), Sep)))
SetParameter 2, OutputArray
if error rtnerror info("error") endif

#5

The extract( function already exists. extract("a,b,c",",",2) returns b, and extract("a,b,c",",",-1) returns 3.


#6

Whoops! I misread Gary’s post.


#7

I realized this morning, that I was expecting some of those separators to do double duty. It should be

arraysize(theSep+replace(theArray,theSep,theSep+theSep)+theSep,theSep+theText+theSep)-1


#8

Thanks for the responses; I’ve been on the road for a few days and had no earlier chance to respond myself.

David’s Custom Statement is exactly what I needed. I thought it existed but couldn’t remember where I had used it before and searches for “arraycount” obviously didn’t turn it up.

Among the ways it’s handy is, for instance, to create an array of cities in a database, then see how many times each city occurs. Currently I’m using it to build a chart to show the frequency of the “Sources” for clients in a database in order to evaluate marketing results.


#9

See - Dave solves our problems while he’s sound asleep :slight_smile:


#10

If you had a field named City, and another field that was always not empty (Status in my example), you could generate a list of the number of appearances of each city with this:

field City
groupup
propagate
Field Status
count
outlinelevel 1
displaydata arrayselectedbuild(cr(), “”, {?(info(“summary”)=1,Status+tab()+City,"")})


#11

Actually there are many easy ways to do it if I want to crunch data. The objective is to sit on a single record and be able to instantly display a chart based on the number of whatevers. Arrays are pretty much the onl way to do that.