Что нового

Аналог ассоциативного массива

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Вот пример и несколько простых функции для создания нечто наподобие ассоциативного массива :smile:.
Используется объект Scripting.Dictionary.

Код:
$oAssocArray = _AssocArray_Create()
_AssocArray_Add($oAssocArray, 'Test', 'Associative Arrays In AutoIt!')

;Значения можно также добавлять/обновлять напрямую:
;$oAssocArray('Test') = 'New Value'

MsgBox(64, 'Доступ к записи массива по названию ячейки', $oAssocArray('Test')) ;Вот это собственно и есть использование типа ассоциативного массива

Func _AssocArray_Create()
	Local $oArray = ObjCreate('Scripting.Dictionary')
	Return $oArray
EndFunc

Func _AssocArray_Add(ByRef $oAssocArray, $sItem, $vValue)
	$oAssocArray.Add($sItem, $vValue)
EndFunc

Func _AssocArray_Delete(ByRef $oAssocArray, $sItem)
	If $oAssocArray.Exists($sItem) Then
		$oAssocArray.Remove($sItem)
	EndIf
EndFunc


Естественно поддерживается только одномерный массив.
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
А что по поводу скорости работы с такими массивами?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR,
Вы опять забыли про
Код:
$oArray.CompareMode
:smile:
 

DarWiM

Продвинутый
Сообщения
527
Репутация
90
madmasles
А это влияет на скорость?
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481

DarWiM

Продвинутый
Сообщения
527
Репутация
90
CreatoR
Я имел ввиду, имеют ли бинарный и текстовый режимы отличия по скорости обработки?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
А оно тут разве нужно?
ИМХО, да. Пример.
Код:
#include <Array.au3>

For $j = 0 To 2
	$oDictionary = ObjCreate("Scripting.Dictionary")
	If Not IsObj($oDictionary) Then Exit 33
	$oDictionary.CompareMode = $j
	For $i = 1 To 10
		If Not $oDictionary.Exists(Chr($i + 64)) Then $oDictionary.add(Chr($i + 64), 'Test' & $i)
	Next
	For $i = 11 To 20
		If Not $oDictionary.Exists(Chr($i + 86)) Then $oDictionary.add(Chr($i + 86), 'Test' & $i)
	Next
	$aKeys = $oDictionary.keys
	_ArrayDisplay($aKeys, 'CompareMode = ' & $j & ' Keys')
	$aItems = $oDictionary.items
	_ArrayDisplay($aItems, 'CompareMode = ' & $j & ' Items')
	$oDictionary = 0
Next

Если убрать проверку (.Exists), то, при CompareMode = 1, ошибка объекта.
Код:
$oAuErr = ObjEvent('AutoIt.Error', '_AuErr')
$oDictionary = ObjCreate("Scripting.Dictionary")
If Not IsObj($oDictionary) Then Exit 33
$oDictionary.CompareMode = 1
For $i = 1 To 10
	$oDictionary.add(Chr($i + 64), 'Test' & $i)
Next
For $i = 11 To 20
	$oDictionary.add(Chr($i + 86), 'Test' & $i)
Next

Func _AuErr()
	ConsoleWrite($oAuErr.number & @LF)
EndFunc   ;==>_AuErr
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
DarWiM [?]
имеют ли бинарный и текстовый режимы отличия по скорости обработки?
Да, бинарный быстрее вроде.

madmasles [?]
ИМХО, да. Пример
Ну я как бы на библиотеку ещё не целился, это просто полезняшка в целях изучения, скорее демонстрация того, что в AutoIt всё же можно использовать нечто вроде ассоциативного массива.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Библиотека по теме кстати уже есть.
 

XpycT

Скриптер
Сообщения
380
Репутация
133
Я тут поигрался немного с "пелезняшкой" и вот что получилось
Код:
$oMenu = ObjCreate("Scripting.Dictionary")
$oMenu_1_Items = ObjCreate("Scripting.Dictionary")
$oMenu_2_Items = ObjCreate("Scripting.Dictionary")

$oMenu_1_Items.Add("MenuItem1", "Menu 1 Item 1")
$oMenu_1_Items.Add("MenuItem2", "Menu 1 Item 2")

$oMenu_2_Items.Add("MenuItem1", "Menu 2 Item 1")
$oMenu_2_Items.Add("MenuItem2", "Menu 2 Item 2")

$oMenu.Add("Menu 1", $oMenu_1_Items)
$oMenu.Add("Menu 2", $oMenu_2_Items)

For $sMenuName In $oMenu.Keys
	ConsoleWrite($sMenuName & @CR)
	For $sItemName In $oMenu.Item($sMenuName).Keys
		ConsoleWrite(@TAB & @TAB & $oMenu.Item($sMenuName).Item($sItemName) & @CR)
	Next
Next


Вроде как смахивает на двумерный массив
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
IgRo [?]
а ассоциативные массивы строковые значения
Числа тоже можно использовать
Код:
#include <Array.au3>

Local $oDict = ObjCreate("Scripting.Dictionary")
$oDict.CompareMode = 0
$oDict.Item(5)
$oDict.Item('5')
$aArray = $oDict.Keys()
_ArrayDisplay($aArray, 'Array')

; Проверим типы
$aArray[0] = VarGetType($aArray[0])
$aArray[1] = VarGetType($aArray[1])
_ArrayDisplay($aArray, 'Array')

Можешь почитать тут
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Обнаружил, что в Scripting.Dictionary нельзя использовать Handle. :scratch:
Код:
#include <GUIConstantsEx.au3>

$oAuErr = ObjEvent('AutoIt.Error', '_AuErr')
$oDict = ObjCreate('Scripting.Dictionary')

$hGui = GUICreate('Test')

$oDict.add('Test', $hGui)
ConsoleWrite('item Test: >' & $oDict.item('Test') & '<' & @LF)

GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd

Func _AuErr()
	ConsoleWrite('Error number: ' & $oAuErr.number & @LF)
EndFunc   ;==>_AuErr
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
madmasles [?]
в Scripting.Dictionary нельзя использовать Handle
Ну почему, очень даже можно:

Код:
$oDict = ObjCreate('Scripting.Dictionary')
$hGui = GUICreate('Handle')
$oDict.Add('Handle', $hGui)

ConsoleWrite('GUICreate:	' & $hGui & ', HWnd(' & HWnd($hGui) & ')' & @LF)
ConsoleWrite('Handle item:	' & $oDict.Item('Handle') & ', HWnd(' & HWnd($oDict.Item('Handle')) & ')' & @LF)

WinSetState(HWnd($oDict.Item('Handle')), '', @SW_SHOW)
Sleep(2000)
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
Ну почему, очень даже можно:
Код:
$oAuErr = ObjEvent('AutoIt.Error', '_AuErr')
$oDict = ObjCreate('Scripting.Dictionary')
$hGui = GUICreate('Handle')
$oDict.Add('Handle', $hGui)

ConsoleWrite('GUICreate:    ' & $hGui & ', HWnd(' & HWnd($hGui) & ')' & @LF)
ConsoleWrite('Handle item:  ' & $oDict.Item('Handle') & ', HWnd(' & HWnd($oDict.Item('Handle')) & ')' & @LF)

WinSetState(HWnd($oDict.Item('Handle')), '', @SW_SHOW)
Sleep(2000)

Func _AuErr()
	ConsoleWrite('Error number: ' & $oAuErr.number & @LF)
EndFunc   ;==>_AuErr
У меня в консоли пишет:
Код:
Error number: 5
GUICreate:    , HWnd(0x00000000)
Handle item:  , HWnd(0x00000000)
AutoIt 3.3.6.1 Win 7 x 86. :blink:

А 3.3.8.1 и выше отрабатывает нормально. Видимо это какой-то косяк в 3.3.6.1.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
madmasles [?]
У меня в консоли пишет

А что это выдаёт:

Код:
ConsoleWrite('Error number: ' & $oAuErr.number & @LF & 'Error description: ' & $oAuErr.description & @LF & 'Scrip line: ' & $oAuErr.scriptline)


?
:scratch:
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
вот пример проверки, какие форматы поддерживает
Код:
#include <Array.au3>

; Типы
Local $aArray[2] = [1, 'Элемент']
Local $bBinary = Binary('0x00204060')
Local $fBoolean = False
Local $hWnd = WinGetHandle('[CLASS:Shell_TrayWnd]')
Local $hPointer = Ptr(-1)
Local $iInt = 1
Local $nFloat = 2.0
Local $sString = 'Некоторый текст'
Local $vKeyword = Default
Local $tStruct = DllStructCreate('wchar[256]')
Local $oObject = ObjCreate("Scripting.Dictionary")

; Проверка ключей
Local $oDict = ObjCreate("Scripting.Dictionary")
$oDict.CompareMode = 0
; $oDict.Item($aArray)
; $oDict.Item($bBinary)
$oDict.Item($fBoolean)
; $oDict.Item($hWnd)
; $oDict.Item($hPointer)
$oDict.Item($iInt)
$oDict.Item($nFloat)
$oDict.Item($sString)
$oDict.Item($vKeyword)
; $oDict.Item($tStruct)
$oDict.Item($oObject)
$aArray1 = $oDict.Keys()
_ArrayDisplay($aArray1, 'Значения ключей')
; Проверим типы
For $i = 0 To 5
	$aArray1[$i] = VarGetType($aArray1[$i])
Next
_ArrayDisplay($aArray1, 'Типы')

; Проверка параметров
Local $oDict2 = ObjCreate("Scripting.Dictionary")
$oDict2.CompareMode = 0
$oDict2.add(0, $aArray)
$oDict2.add(1, $bBinary)
$oDict2.add(2, $fBoolean)
$oDict2.add(3, $hWnd)
$oDict2.add(4, $hPointer)
$oDict2.add(5, $iInt)
$oDict2.add(6, $nFloat)
$oDict2.add(7, $sString)
$oDict2.add(8, $vKeyword)
$oDict2.add(9, $tStruct)
$oDict2.add(10, $oObject)

$aArray1 = $oDict2.Items()
_ArrayDisplay($aArray1[0], 'Точно массив?')

_ArrayDisplay($aArray1, 'Значения параметров')
; Проверим типы
For $i = 0 To 10
	$aArray1[$i] = VarGetType($aArray1[$i])
Next
_ArrayDisplay($aArray1, 'Типы')
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
А что это выдаёт:
Код:
Error number: 5
Error description: 
Scrip line: 4
3.3.6.1


Добавлено:
Сообщение автоматически объединено:

AZJIO [?]
вот пример проверки
В 3.3.6.1 (у меня) еще $hPointer и $tStruct ошибку выдают.
А 3.3.8.1 и выше все переменные поддерживаются без проблем.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
madmasles [?]
В 3.3.6.1 (у меня) еще $hPointer и $tStruct ошибку выдают.
Да действительно, 3.3.6.1 с этими типами данных не справляется.
В 3.3.8.1 с этим проблем нет, так что хороший повод обновиться :smile:.
 
Верх