AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 09.10.2012, 10:22   #1  
McArrow is offline
McArrow
Участник
 
45 / 38 (2) +++
Регистрация: 18.05.2009
Хранение массива в Map
Здравствуйте, коллеги.

Проблема: нужно хранить массив в Map.

Пример:
X++:
static void ArrayMapExample2(Args _args)
{
    Dimension value, result;
    Map map;
    MapEnumerator me;
    int64 key;
;
    map = new Map(Types::Int64, Types::String);

    key = 1; value[1] = 'abc'; value[2] = 'def'; value[3] = 'jhi';
    map.insert(key, value);

    key = 2; value[1] = '3.0'; value[2] = '2.0'; value[3] = '1.0';
    map.insert(key, value);

    key = 3; value[1] = '+++'; value[2] = '???'; value[3] = '!!!';
    map.insert(key, value);

    me = map.getEnumerator();
    while (me.moveNext())
    {
        key = me.currentKey();
        result = me.currentValue();
        info(strfmt('%1;%2;%3;%4', key, result[1], result[2], result[3]));
    }
}
результат:
X++:
1;;;
2;;;
3;;;
Правильно ли я понял что, массив в map (set, list) напрямую хранить нельзя? DAX 4.0 SP2

Последний раз редактировалось McArrow; 09.10.2012 в 10:31.
За это сообщение автора поблагодарили: asd1274 (1).
Старый 09.10.2012, 10:42   #2  
ConsAx
Гость
 
n/a
Цитата:
Сообщение от McArrow Посмотреть сообщение
Здравствуйте, коллеги.

Проблема: нужно хранить массив в Map.

Пример:
[XPP]
static void ArrayMapExample2(Args _args)
{
Dimension value, result;
Map map;
MapEnumerator me;
int64 key;
;
map = new Map(Types::Int64, Types::String);

Правильно ли я понял что, массив в map (set, list) напрямую хранить нельзя? DAX 4.0 SP2
Вы пробуете массив хранить в строке. Поэтому получаете, что получаете.
В данном случае, возможно, есть смысл в качестве значений использовать не строку, а контейнер?

Container con;

map = new Map(Types::Int64, Types::Container);

key = 1;
con =['abc', 'def', 'jhi'];

map.insert(key, con );

Последний раз редактировалось ConsAx; 09.10.2012 в 10:45.
За это сообщение автора поблагодарили: McArrow (1).
Старый 09.10.2012, 11:11   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
А класс Array для представления масива вас не устроит? Если устроит, то тогда можно использовать Маp класссов Array.
X++:
map = new Map(Types::Int64, Types::Class);
Старый 09.10.2012, 11:43   #4  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
"Массив" и EDT типа массив - это "две большие разницы" Types::String предполагает хранение переменной типа String, но никак не массива.

В данном случае, можно инкапсулировать сложный тип данных в контейнер примерно так

X++:
static void ArrayMapExample2(Args _args)
{
    Dimension value, result;
    Map map;
    MapEnumerator me;
    int64 key;
    ;
    
    map = new Map(Types::Int64, Types::Container);

    key = 1; value[1] = 'abc'; value[2] = 'def'; value[3] = 'jhi';
    map.insert(key, [value]);

    key = 2; value[1] = '3.0'; value[2] = '2.0'; value[3] = '1.0';
    map.insert(key, [value]);

    key = 3; value[1] = '+++'; value[2] = '???'; value[3] = '!!!';
    map.insert(key, [value]);

    me = map.getEnumerator();
    while (me.moveNext())
    {
        key = me.currentKey();
        [result] = me.currentValue();
        info(strfmt('%1;%2;%3;%4', key, result[1], result[2], result[3]));
    }
}
Хотя, если все-равно используется контейнер, то какой смысл использовать Dimension? Проще уж сделать как написал ConsAx
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 09.10.2012, 12:23   #5  
McArrow is offline
McArrow
Участник
 
45 / 38 (2) +++
Регистрация: 18.05.2009
Вообще интересная ситуация.

Если поменять
Dimension value, result;
на явное объявление массива
str value[10], result[10];

то получается ошибка времени выполнения - Неверная операция над массивом данного типа - что как-бы намекает на некорректность кода.

Если же сменить тип данных со string на real (как нужно было в реальной задаче), то джоб выполняется без ошибок, но в результате выполнения нули, а на больших выборках - мусор. При этом аксапта ни на что не ругается

X++:
static void ArrayMapExample3(Args _args)
{
    real value[3];
    real result[3];
    Map map;
    MapEnumerator me;
    int64 key;
;
    map = new Map(Types::Int64, Types::Real);

    key = 1; value[1] = 1.0; value[2] = 2.0; value[3] = 3.0;
    map.insert(key, value);

    key = 2; value[1] = 3.0; value[2] = 2.0; value[3] = 1.0;
    map.insert(key, value);

    key = 3; value[1] = 1.0; value[2] = 3.0; value[3] = 2.0;
    map.insert(key, value);

    me = map.getEnumerator();
    while (me.moveNext())
    {
        key = me.currentKey();
        result = me.currentValue();
        info(strfmt('%1;%2;%3;%4', key, result[1], result[2], result[3]));
    }
}
Получается, что в зависимости от типа данных массива система здесь ведёт себя по-разному.
Думаю свернуть свои эксперименты с массивами и использовать контейнер. Спасибо!
Старый 11.10.2012, 09:19   #6  
online
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Так а что помешало использовать класс Array? Берем и делаем!
X++:
static void ES_ArrayMapExample(Args _args)
{
    Array           a       = new Array(Types::String);
    Array           result  = new Array(Types::String);
    Map             map     = new Map(Types::Int64, Types::Class);
    MapEnumerator   me;
    int64 key;
    ;

    a.value(1, 'abc');
    a.value(2, 'def');
    a.value(3, 'jhi');
    map.insert(1, a);

    a.value(1, '3.0');
    a.value(2, '2.0');
    a.value(3, '1.0');
    map.insert(2, a);

    a.value(1, '+++');
    a.value(2, '???');
    a.value(3, '!!!');
    map.insert(3, a);

    me = map.getEnumerator();
    while (me.moveNext())
    {
        key = me.currentKey();
        result = me.currentValue();
        info(strfmt('%1;%2;%3;%4', key, result.value(1), result.value(2), result.value(3)));
    }
}
__________________
// no comments
Старый 11.10.2012, 09:44   #7  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от dech Посмотреть сообщение
Так а что помешало использовать класс Array? Берем и делаем!
Я думаю, что целью было запихнуть в Map стандартный Dimension. В этом случае самый простой выход их ситуации подсказал Владимир Максимов.

Если хранить нужно произвольные масивы, то я тоже за вариант с классом Array.
Старый 11.10.2012, 13:05   #8  
McArrow is offline
McArrow
Участник
 
45 / 38 (2) +++
Регистрация: 18.05.2009
При хранении в Map'е контейнеров, по моим измерениям, имеется значительное преимущество в производительности.

X++:
static void MDL_testMapArray(Args _args)
{
    Array array;
    int i, key;
    Map map = new Map(Types::Integer, Types::Class);
    MapEnumerator me;
    TimeOfDay startTime;

    int getKey()
    {
        return xGlobal::randomPositiveInt32();
    }
    int getValue()
    {
        return xGlobal::randomPositiveInt32();
    }
;
    setprefix('Array class в Map');
    startTime = timenow();
    for (i = 1; i <= 10000; i ++)
    {
        array = new Array(Types::Integer);
        array.value( 1, getValue());
        array.value( 2, getValue());
        array.value( 3, getValue());
        array.value( 4, getValue());
        array.value( 5, getValue());
        array.value( 6, getValue());
        array.value( 7, getValue());
        array.value( 8, getValue());
        array.value( 9, getValue());
        array.value(10, getValue());
        map.insert(getKey(), array);
    }
    me = map.getEnumerator();
    while (me.moveNext())
    {
        key = me.currentKey();
        array = me.currentValue();
    }
    info(strfmt('Выполнено за %1 сек.', timenow() - startTime));
}
X++:
static void MDL_testMapCon(Args _args)
{
    container value;
    int i, key;
    Map map = new Map(Types::Integer, Types::Container);
    MapEnumerator me;
    TimeOfDay startTime;

    int getKey()
    {
        return xGlobal::randomPositiveInt32();
    }
    int getValue()
    {
        return xGlobal::randomPositiveInt32();
    }
;
    setprefix('Container в Map');
    startTime = timenow();
    for (i = 1; i <= 10000; i ++)
    {
        value = [getValue(), getValue(), getValue(), getValue(), getValue(), getValue(), getValue(), getValue(), getValue(), getValue()];
        map.insert(getKey(), value);
    }
    me = map.getEnumerator();
    while (me.moveNext())
    {
        key = me.currentKey();
        value = me.currentValue();
    }
    info(strfmt('Выполнено за %1 сек.', timenow() - startTime));
}
результат:
X++:
Array class  Map
  19 .
Container  Map
  7 .
Теги
dimensions, map

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Классы коллекций (инициализация, сериализация): List, Set, Map. petergunn DAX: База знаний и проекты 12 06.11.2024 18:38
Помещение временной таблицы в Map Lemming DAX: Программирование 20 19.10.2017 14:16
Не корректная сортировка в Map-e и Set-е. AX2009 RU5 Pustik DAX: Программирование 12 03.05.2016 21:28
Dynamics AX: Map Object Sorting - a real issue Blog bot DAX Blogs 7 15.10.2008 12:02
MAP vs Class. В чем идейная необходимость в MAP-ах? А что если использовать Class вместо MAP? Hub DAX: Программирование 16 11.08.2008 16:58

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 21:19.