forked from rosh/MQL5Book
141 lines
4.2 KiB
MQL5
141 lines
4.2 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| ArrayUtils.mqh |
| |
//| Copyright (c) 2021-2022, MetaQuotes Ltd. |
| |
//| https://www.mql5.com |
| |
//+------------------------------------------------------------------+
| |
| |
//+------------------------------------------------------------------+
| |
//| Helper function to remove duplicates from array |
| |
//+------------------------------------------------------------------+
| |
template<typename T>
| |
int ArrayUnique(T &array[])
| |
{
| |
const int n = ArraySize(array);
| |
if(n <= 1) return 0;
| |
int w = 0;
| |
for(int i = 1; i < n; ++i)
| |
{
| |
if(array[i] == array[w])
| |
{
| |
// skip it
| |
}
| |
else if(w < i - 1)
| |
{
| |
array[++w] = array[i];
| |
}
| |
else
| |
{
| |
++w;
| |
}
| |
}
| |
return n - ArrayResize(array, w + 1);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Helper function to remove empty elements from array |
| |
//+------------------------------------------------------------------+
| |
template<typename T>
| |
void ArrayPurge(T &array[], const T empty)
| |
{
| |
const int count = ArraySize(array);
| |
int write = 0;
| |
int i = 0;
| |
while(i < count)
| |
{
| |
while(i < count && array[i] == empty)
| |
{
| |
i++;
| |
}
| |
| |
while(i < count && array[i] != empty)
| |
{
| |
if(write < i)
| |
{
| |
array[write] = array[i];
| |
}
| |
i++;
| |
write++;
| |
}
| |
}
| |
ArrayResize(array, write);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Helper class to remove elements from array by predicate |
| |
//+------------------------------------------------------------------+
| |
template<typename T>
| |
class ArrayPurger
| |
{
| |
typedef bool (*PURGER)(const T &element);
| |
public:
| |
ArrayPurger(T &array[], PURGER func)
| |
{
| |
const int count = ArraySize(array);
| |
int write = 0;
| |
int i = 0;
| |
while(i < count)
| |
{
| |
while(i < count && func(array[i]))
| |
{
| |
i++;
| |
}
| |
| |
while(i < count && !func(array[i]))
| |
{
| |
if(write < i)
| |
{
| |
array[write] = array[i];
| |
}
| |
i++;
| |
write++;
| |
}
| |
}
| |
ArrayResize(array, write);
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Output byte array in hex |
| |
//+------------------------------------------------------------------+
| |
void ByteArrayPrint(const uchar &bytes[],
| |
const int row = 16, const string separator = " | ",
| |
const uint start = 0, const uint count = WHOLE_ARRAY)
| |
{
| |
string hex = "";
| |
const int n = (int)MathCeil(MathLog10(ArraySize(bytes) + 1));
| |
for(uint i = start; i < MathMin(start + count, ArraySize(bytes)); ++i)
| |
{
| |
if(i % row == 0 || i == start)
| |
{
| |
if(hex != "") Print(hex);
| |
hex = StringFormat("[%0*d]", n, i) + " ";
| |
}
| |
hex += StringFormat("%02X", bytes[i]) + separator;
| |
}
| |
if(hex != "") Print(hex);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Output number array in hex |
| |
//+------------------------------------------------------------------+
| |
template<typename T>
| |
void HexArrayPrint(const T &bytes[],
| |
const int row = 16, const string separator = " | ",
| |
const uint start = 0, const uint count = WHOLE_ARRAY)
| |
{
| |
const int size = sizeof(T) / sizeof(uchar) * 2;
| |
string hex = "";
| |
const int n = (int)MathCeil(MathLog10(ArraySize(bytes) + 1));
| |
for(uint i = start; i < MathMin(start + count, ArraySize(bytes)); ++i)
| |
{
| |
if(i % row == 0 || i == start)
| |
{
| |
if(hex != "") Print(hex);
| |
hex = StringFormat("[%0*d]", n, i) + " ";
| |
}
| |
hex += StringFormat("%0*x", size, bytes[i]) + separator;
| |
}
| |
if(hex != "") Print(hex);
| |
}
| |
| |
//+------------------------------------------------------------------+
|