Причин может быть несколько. Скорее всего либо несовместимость типов, либо неправильная работа с указателями. Также нельзя исключать особенности работы с шаблонными методами (там тоже свои нюансы).
Доброго времени суток! А не подскажете как циклом пройти по всему словарю, удаляя при этом пары по определенному условию, что-то не могу догнать. Вот пример такой задачи.
#include <Dictionary.mqh>
class CInt : public CObject
{
public:
int value;
CInt(int _value = 0) : value(_value) {}
};
CDictionary d;
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+intOnInit()
{
d.FreeMode(true);
for(int i = 0; i < 10; ++i)
{
CInt *int_value = new CInt(i);
d.AddObject(i, int_value);
}
for(CInt *node = d.GetFirstNode(); node != NULL;)
{
if(node.value % 2 == 0)
// d.DeleteCurrentNode() или d.DeleteObjectByKey(node.value);// Как дальше итерироваться по словарю???
}
return(INIT_SUCCEEDED);
}
Доброго времени суток! А не подскажете как циклом пройти по всему словарю, удаляя при этом пары по определенному условию, что-то не могу догнать. Вот пример такой задачи.
Хороший вопрос. Сейчас проверил удаление Вашим способом - оно не работает корректно. Буду разбираться.
1. Обновляем версию Dictionary на ту что прикреплена к этому посту.
2. Запускаем тестовый скрипт по удалению четных элементов.
Удаление нужно делать в два прохода:
intOnStart()
{
d.FreeMode(true);
for(int i = 0; i < 10; ++i)
{
CInt *int_value = new CInt(i);
d.AddObject(i, int_value);
}
//-- Создаем список ключей для удаления
CArrayInt delKeys;
for(CInt *node = d.GetFirstNode(); node != NULL; node = d.GetNextNode())
{
if(node.value % 2 == 0)
delKeys.Add(node.value);
}
//-- Удаляем объекты назначенные на удаление, каждый отдельно.for(int i = 0; i < delKeys.Total(); i++)
d.DeleteObjectByKey(delKeys.At(i));
for(CInt *node = d.GetFirstNode(); node != NULL; node = d.GetNextNode())
{
printf(node.value);
}
return(INIT_SUCCEEDED);
}
По поводу метода DeleteCurrentObject():
Данный метод нужно использовать только совместно с функцией ContainsKey(). Единственная причина по которой он доступен как public это то, что именно в этом кейсе вызов метода позволяет сэкономить время на повторном позиционировании указателя. Т.е. типичный и единственный случай его использования это 1. Проверили есть ли ключ, 2. если есть - удалили его быстро этим методом.
Технически возможно однопроходное удаление как Вы ожидаете. Но сложновато будет. Поэтому пока нет, только в два прохода. С точки зрения словаря как распределенной структуры данных, двухпроходное удаление является более канонически правильным решением. Это только на уровне пользователя кажется что удаление идет последовательно, на самом деле все иначе устроено. В плане перфоманса однопроходное удаление не принесет каких-либо бенефитов. В плане удобства - да, это может быть более удобным.
Технически возможно однопроходное удаление как Вы ожидаете. Но сложновато будет. Поэтому пока нет, только в два прохода. С точки зрения словаря как распределенной структуры данных, двухпроходное удаление является более канонически правильным решением. Это только на уровне пользователя кажется что удаление идет последовательно, на самом деле все иначе устроено. В плане перфоманса однопроходное удаление не принесет каких-либо бенефитов. В плане удобства - да, это может быть более удобным.
Причин может быть несколько. Скорее всего либо несовместимость типов, либо неправильная работа с указателями. Также нельзя исключать особенности работы с шаблонными методами (там тоже свои нюансы).
А вообще лучше воспользоваться готовым торговым движком, много времени и нервом сэкономите: https://www.mql5.com/ru/articles/2166
Доброго времени суток! А не подскажете как циклом пройти по всему словарю, удаляя при этом пары по определенному условию, что-то не могу догнать. Вот пример такой задачи.
Доброго времени суток! А не подскажете как циклом пройти по всему словарю, удаляя при этом пары по определенному условию, что-то не могу догнать. Вот пример такой задачи.
Хороший вопрос. Сейчас проверил удаление Вашим способом - оно не работает корректно. Буду разбираться.
Хороший вопрос. Сейчас проверил удаление Вашим способом - оно не работает корректно. Буду разбираться.
оно и не должно работать корректно в общем случае.
правильный способ множественного удаления из ассоциативного массива - собрать массив удаляемых ключей, затем удалить по ключу.
оно и не должно работать корректно в общем случае.
правильный способ множественного удаления из ассоциативного массива - собрать массив удаляемых ключей, затем удалить по ключу.
Это понятно, но опять же лишние телодвижения.
Хороший вопрос. Сейчас проверил удаление Вашим способом - оно не работает корректно. Буду разбираться.
Спасибо за отклик!
оно и не должно работать корректно в общем случае.
правильный способ множественного удаления из ассоциативного массива - собрать массив удаляемых ключей, затем удалить по ключу.
Да вот в том-то и дело, что даже такой способ вдруг вызвал странный баг. Там явно ошибка. Буду разбираться в чем дело.
Пока могу посоветовать создать новый словарь, и в него добавлять значения которые не нужно удалять. Затем старый очистить. Это 100% сработает.
Значит так:
1. Обновляем версию Dictionary на ту что прикреплена к этому посту.
2. Запускаем тестовый скрипт по удалению четных элементов.
Удаление нужно делать в два прохода:
По поводу метода DeleteCurrentObject():
Данный метод нужно использовать только совместно с функцией ContainsKey(). Единственная причина по которой он доступен как public это то, что именно в этом кейсе вызов метода позволяет сэкономить время на повторном позиционировании указателя. Т.е. типичный и единственный случай его использования это 1. Проверили есть ли ключ, 2. если есть - удалили его быстро этим методом.
Это понятно, но опять же лишние телодвижения.
Технически возможно однопроходное удаление как Вы ожидаете. Но сложновато будет. Поэтому пока нет, только в два прохода. С точки зрения словаря как распределенной структуры данных, двухпроходное удаление является более канонически правильным решением. Это только на уровне пользователя кажется что удаление идет последовательно, на самом деле все иначе устроено. В плане перфоманса однопроходное удаление не принесет каких-либо бенефитов. В плане удобства - да, это может быть более удобным.
Технически возможно однопроходное удаление как Вы ожидаете. Но сложновато будет. Поэтому пока нет, только в два прохода. С точки зрения словаря как распределенной структуры данных, двухпроходное удаление является более канонически правильным решением. Это только на уровне пользователя кажется что удаление идет последовательно, на самом деле все иначе устроено. В плане перфоманса однопроходное удаление не принесет каких-либо бенефитов. В плане удобства - да, это может быть более удобным.
Спасибо.
Кажется, я обнаружил ошибку при удалении элемента и попытке перейти к последнему элементу:
Ошибка в CDictionary.mqh будет:
invalid pointer access in 'Dictionary.mqh' (463,9)
Кто-нибудь может подтвердить это? Есть идеи, как исправить?
Это была ошибка в строке 500 && 501 в реализации проверки указателей.
Исправлено с помощью встроенной функции CheckPointer().