# Different Array Number

131

Hi,

I have a problem to count the number of different integer in an array.

For exemple: in MyArray {5,7,5,3,3,4,7,7,3,4,4,3}  There is 4 different integer (3, 4, 5 and 7)

I would like to return  int DifArrayNbr=4;

I've tried to did it with some "for() " or "while()" but it's so hard to make a correctly loop

Mike

20208

```//{ Typedefs
#define  INDEX    uint           // Zero based.
#define  COUNT    uint           //  One based.
#define INV_INDEX               UINT_MAX
#define INV_COUNT               UINT_MAX
//} Typedefs
template <typename T>
COUNT    count_unique(T& array[], INDEX iEnd=INV_INDEX, INDEX iBeg=0){
if(iEnd == INV_INDEX)   iEnd  = ArraySize(array);
if(iEnd == iBeg)  return 0;            // Empty array.
ArraySort(array, iEnd - iBeg, iBeg);
COUNT    n  = 1;                       // Last is unique;
while(--iEnd > iBeg) if(array[iEnd] != array[iEnd-1] )   ++n;
return n;
}
/////////////////////////////////////////////////////
int      MyArray[] ={5,7,5,3,3,4,7,7,3,4,4,3};
COUNT    DifArrayNbr=count_unique(MyArray); // 4
```
22

whroeder1:
What is "COUNT" and "INDEX" types?
20208

Put on your glasses and look at the code again.
3023

aslkdjf:
What is "COUNT" and "INDEX" types?

The both are uint. This is whroeder's style but the code is worth it. Maybe it can be improved for double and float by using DBL_EPSILON.

20208

Petr Nosek: Maybe it can be improved for double and float by using DBL_EPSILON.
```//{ Typedefs
#define  PRICE double            // A PRICE
#define     PRICE_MAX   (PRICE)EMPTY_VALUE
#define     PRICE_MIN   (PRICE)0
#define     CHANGE      PRICE    // Difference of two prices.
#define  INDEX    uint           // Zero based.
#define  COUNT    uint           //  One based.
#define  MONEY    double
#define  LOTS     double
#define  SYMBOL   string
//} Typedefs
```
Don't need DBL_EPSILON as Tick Size or Point is sufficient.
11675

Mickael Arditi:

Hi,

I have a problem to count the number of different integer in an array.

For exemple: in MyArray {5,7,5,3,3,4,7,7,3,4,4,3}  There is 4 different integer (3, 4, 5 and 7)

I would like to return  int DifArrayNbr=4;

I've tried to did it with some "for() " or "while()" but it's so hard to make a correctly loop

Mike

I would have do it so, it's not as nerdy as the above snippet, but it works well :

```#include <Arrays\ArrayInt.mqh> // Include lib
//
int MyArray[]={5,7,5,3,3,4,7,7,3,4,4,3};
//
int CountItem(int &Array[])
{
CArrayInt *TempArray=new CArrayInt(); CArrayInt *ItemsFound=new CArrayInt(); int value = 0;
TempArray.AssignArray(MyArray); TempArray.Sort();
for(int x=0;x<TempArray.Total();x++) { if(ItemsFound.Search(TempArray.At(x))<0) { ItemsFound.Add(TempArray.At(x)); ItemsFound.Sort(); } else { continue; } }
printf("*** Items found in array : %g",ItemsFound.Total()); value = ItemsFound.Total();
delete(TempArray); delete(ItemsFound);
return(value);
}
//
DifArrayNbr = CountItem(MyArray); // Function call
//+------------------------------------------------------------------+```
3023

whroeder1:
Don't need DBL_EPSILON as Tick Size or Point is sufficient.

I've a little bit edited your function and it gives better results in my opinion. The last element in the double array is 3 like the previous one. For price is Tick Size or Point sufficient but for indicator values...

UPDATE: see the next post

```template <typename T>
uint CountUnique(T& array[],const char precision=-1,uint iEnd=UINT_MAX,const uint iBeg=0)
{
if(iEnd==UINT_MAX) iEnd=ArraySize(array);
if(iEnd==iBeg) return(0); // Empty array.
ArraySort(array,iEnd-iBeg,iBeg);
uint count=1; // Last is unique;
string tn=typename(T);
if((tn=="double"||tn=="float"))
{
if(precision>-1)
{
while(--iEnd>iBeg)
if(DoubleToString(array[iEnd],precision)!=DoubleToString(array[iEnd-1],precision)) count++;
}
else
while(--iEnd>iBeg)
if(fabs(array[iEnd]-array[iEnd-1])>DBL_EPSILON*10) count++; // Too small difference => equal
}
else
while(--iEnd>iBeg) if(array[iEnd]!=array[iEnd-1]) count++;
return(count);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

double dblArr[6]={1.0000001,1.0,1.4,1.399999,3.0,90000.0*123456789123456789.0/(30000.0*123456789123456789.0)};
int intArr[12]={5,7,5,3,3,4,7,7,3,4,4,3};
uint DifDblArrayNbr,DifIntArrayNbr;

DifDblArrayNbr=CountUnique(dblArr);    // 5 (in your case 6)
DifDblArrayNbr=CountUnique(dblArr,6);  // 4
DifDblArrayNbr=CountUnique(dblArr,5);  // 3
DifDblArrayNbr=CountUnique(dblArr,0);  // 2

DifIntArrayNbr=CountUnique(intArr);    // 4```
3023

Update: less code, same results

```template <typename T>
uint CountUnique(T& array[],const char precision=-1,uint iEnd=UINT_MAX,const uint iBeg=0)
{
if(iEnd==UINT_MAX) iEnd=ArraySize(array);
if(iEnd==iBeg) return(0); // Empty array.
ArraySort(array,iEnd-iBeg,iBeg);
uint count=1; // Last is unique;
string tn=typename(T);
if((tn=="double"||tn=="float"))
{
double difference=(precision>-1 && precision<16)?(pow(10.0,-1.0*precision)-pow(10.0,-1.0*(precision+1))):DBL_EPSILON*10;
while(--iEnd>iBeg)
if(fabs(array[iEnd]-array[iEnd-1])>difference) count++; // Too small difference => equal
}
else
while(--iEnd>iBeg) if(array[iEnd]!=array[iEnd-1]) count++;
return(count);
}```
131

Thank you very much for all your help! :) Have a very nice day ;)