Что нового

MapExists ошибка

RaZum

Знающий
Сообщения
78
Репутация
14
Это только у меня падает AutoIt при определении отрицательного индекса в map?
AutoIt код:
Local $map[]
MapExists ($map, -1)
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Похоже на то, что функция ищет не те ключи, которые мы создаём, а те индексы, которые присваиваются при создании map: ближайшие свободные числа (то есть в случае, когда из map ничего не удаляется, это попросту индексы 0, 1, 2, ...).
Код:
Local $mMap[]
MapAppend($mMap, "a")
MapAppend($mMap, "b")
MapAppend($mMap, "c")
MsgBox(4096, "", MapExists($mMap, "a") & ", " & MapExists($mMap, "b") & ", " & MapExists($mMap, "c") & ", " & MapExists($mMap, 0) & ", " & MapExists($mMap, 1) & ", " & MapExists($mMap, 2))
Этот скрипт выдаёт: "0, 0, 0, 1, 1, 1".

Польза сомнительна.

Лично я использую другой способ для работы с ассоциативными массивами.
Код:
$oDict = ObjCreate('Scripting.Dictionary')
Этот ищет то, что требуется.

Ссылка на справку с сайта "AZJIO".
 
Последнее редактирование:
Автор
R

RaZum

Знающий
Сообщения
78
Репутация
14
MapAppend - "Значение добавляется с помощью последующего доступного целочисленного ключа" - т.е. последующего свободного целочисленного индекса (см. справку)
MapAppend (Map, Value)
Value - Not Key !
Добавляется значение, а ключ назначает сама функция!
Возврат: "Целочисленный ключ, использованный при добавлении значения" - тот самый целочисленный индекс, который назначила сама функция.
Поэтому MapExists и подтверждает, что ключей "a", "b", "c" - нет, а целочисленные 0, 1, 2 - есть.
Так что в примере выше, ничего странного нет.
 

Alecsis

Осваивающий
Сообщения
101
Репутация
41
Что-то мне подсказывает, неспроста в официальном help-е английским по жёлтому, да ещё в красной рамке грозное предупреждение насчёт Map = фишка экспериментальная. «Warning: This feature is experimental. It may not work, may contain bugs or may be changed or removed without notice»©
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
Многие функции с Scripting.Dictionary переписал под MAP и десятки других сделал и к моему удивлению сейчас обнаружил, что функция MapAppend() нигде не задействована.
Проще создавать библиотеку через $mMap[Name]=Value
Но Name переводить в тип String, т.к. с отрицательным числом вылетает ошибка $mMap[-1]=0
А с положительными числами тоже есть нюансы, '100' и 100 это разные вещи для MAP ...

Код:
#include <Array.au3>

Local $mMap[]
MapAppend($mMap,'a')
MapAppend($mMap,'b')
MapAppend($mMap,'c')
$mMap['a']=0
$mMap['b']=1
$mMap['c']=2
$mMap['-1']=-1
; $mMap[-1]=-1
MapAppend($mMap,'-2')
$mMap['100']='String'
$mMap[100]='Int'
$mMap['vova']=1
$mMap['Vova']=2

$R=MapKeys($mMap)
_ArrayDisplay($R,'MapKeys($mMap)')
$aMap=_Map_Array($mMap)
_ArrayDisplay($aMap,'_Map_Array($mMap)')
MsgBox(4096,'',MapExists($mMap,'a')&','&MapExists($mMap,'b')&','&MapExists($mMap,'c')&','&MapExists($mMap,0)&','&MapExists($mMap,1)&','&MapExists($mMap,2))

Func _Map_Array($vValue)
  Local $aRet[UBound($vValue)][2],$n=0
  For $i In MapKeys($vValue)
    Local $vTag=$vValue[$i],$b='|'&VarGetType($vTag)&'|'
    $aRet[$n][0]=$i
    $aRet[$n][1]=StringInStr('|Map|Array|Object|DLLStruct|Function|UserFunction|',$b)? $b : $vTag
    $n+=1
  Next
  Return $aRet
EndFunc
 
Последнее редактирование:
Автор
R

RaZum

Знающий
Сообщения
78
Репутация
14
Да, есть нюансы, но если подумать, то map просто более щипетилен к типу и виду ключей, но тем он и хорош.
Отрицательное значение целочисленных индексов могли бы использовать для упрощенного удаления целочисленных ключей из map, но это уже желания.
В общем как я понял, эта ошибка имеет место быть не только у меня.
Сообщение автоматически объединено:

Многие функции с Scripting.Dictionary переписал под MAP и десятки других сделал и к моему удивлению сейчас обнаружил, что функция MapAppend() нигде не задействована.
Проще создавать библиотеку через $mMap[Name]=Value
Но Name переводить в тип String, т.к. с отрицательным числом вылетает ошибка $mMap[-1]=0
А с положительными числами тоже есть нюансы, '100' и 100 это разные вещи для MAP ...
MapAppend можно использовать при добавлении обезличенных данных. Когда данные есть, и их обязательно нужно добавить конкретно в этот map, а названия для ключа на этот момент нет.
Впрочем, это уже нюансы...
 
Последнее редактирование:

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
более щипетилен к типу и виду ключей, но тем он и хорош
Не соглашусь с тем, что хорош. Map полностью выбивается из концепции AutoIt.
1. Ключ, фактически, переменная. А имена переменных в AutoIt регистронезависимы. Даже вызов метода объекта и обращение к полю структуры не зависит от регистра. А в map зависит. То есть $mMap.a <> $mMap.A
2. AutoIt - язык с динамической типизацией. А в map нужно думать о типе ключа. Потому что $mMap["10"] <> $mMap[10]. И при получении ключей через MapKeys совершенно непонятно - является ключ числом или строкой. Приходится использовать VarGetType.
3. Совершенно нелогичная функция MapAppend. Зачем добавлять неименованное значение и получать его индекс? Для этого есть массивы.
Как вам такая скрытая перезапись значения ключа?
Код:
Local $mMap[]
$mMap[1] = 111
MapAppend($mMap, 222)
$mMap[2] = 333
ConsoleWrite($mMap[2] & @CRLF) ; 333

Поэтому, map недостаточно "прозрачна" для пользователей AutoIt. И новичков будет больше путать, чем помогать.
 
Последнее редактирование:
  • Like
Реакции: Oki
Автор
R

RaZum

Знающий
Сообщения
78
Репутация
14
Никакой скрытой перезаписи. Для этого используют, выше упоминаемый, MapExists.

Я считаю небрежностью добавлять значение в любой вид переменной, без соблюдения логической последовательности, либо без предварительной её проверки, тем более в массив/map. В противном случае теряется смысл переменной, да и всего кодинга.

Если например Scripting.Dictionary более гибок в использовании, то он и медленнее, а map хоть и без излишеств и поблажек, но за это он и более быстр.

В общем, для языка он только положителен, т.к. предоставляет альтернативу в выборе инструментов кодинга.

Странно видеть такое: "И новичков будет больше пугать, чем помогать."
 
Автор
R

RaZum

Знающий
Сообщения
78
Репутация
14
Извиняюсь, но смысл недалёк.

Вопрос изначальный прояснён, по этому тему можно закрывать.
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
какой был мотив переписывания?
Скорость. Если работаешь со строками 10-20.000 разница незаметна.
Недавно занимался Ёфикацией - библиотека 108.000 слов - то MAP выграл по скорости заполнения и проверке содержимого в библиотеке
Занимался генератором слов - выграл System.Collections.Hashtable, т.к. там порой идёт счёт на миллионы...
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
При маленьких размерах небольшая.
При заполнении 100.000 слов - это меньше секунды, MAP у меня показывает 0.5 сек. , Scripting.Dictionary - 0.8 сек. (это прямое добавление в цикле без условий).
Что касается больших размеров тут и MAP и Scripting.Dictionary одинаково отстают - заполнение словаря с 420.000 словами заняло примерно 18-25 секунд. System.Collections.Hashtable это сделал за 4 секунды.
Конечно ради 0.5 сек. - 0.8 сек и парится не надо , но при использовании MAP меньше кода при компиляции, да и уже привычнее стал.
Про скорость и методы тут более подробно https://www.autoitscript.com/forum/topic/204691-mapdictionaryhashtable-which-hash-algorithm-is-used/
 
Последнее редактирование:
Верх