//{ 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
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.
//{ 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 //} TypedefsDon't need DBL_EPSILON as Tick Size or Point is sufficient.
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
Can someone help me please?
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 //+------------------------------------------------------------------+
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
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); }
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
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
Can someone help me please?
Mike