1 (изменено: seriyforum, 2018-04-28 23:41:12)

Тема: AHK: Сравнение переменной с масивом

Подскажите как сделать условие, где 1 переменная будет сравниваться с массивом, чтобы не делать 100 условий через or и т.д , если она соответствует хоть 1 элементу массива, то условие выполняется.

2 (изменено: stealzy, 2018-04-29 00:06:08)

Re: AHK: Сравнение переменной с масивом

Если вы откроете справку, то в разделе "Object types → Object" найдете множество встроенных методов, один из которых делает именно то, что вам нужно.

3

Re: AHK: Сравнение переменной с масивом

Почитал, но так и не нашёл решения.
Приведите пример, если не сложно.

4

Re: AHK: Сравнение переменной с масивом

Кстати, тоже, не нашёл. Всегда пользовался перебором:


arr := [10, 97, "тридцать три", 0x1C]
var := "тридцать три"
if (VarInArr(var, arr))
	MsgBox, Yes
else
	MsgBox, No
ExitApp
VarInArr(var, arr) {
	Loop,% arr.Length()
		if (arr[ A_Index ] == var)
			return A_Index
	return 0
}

5 (изменено: teadrinker, 2018-04-29 00:32:02)

Re: AHK: Сравнение переменной с масивом

KusochekDobra пишет:
Loop,% arr.Length()

Я бы пользовался циклом For-loop, свойство Length годится только для линейного массива, ключи которого начинаются с единицы и идут без пропусков.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6

Re: AHK: Сравнение переменной с масивом

Хотя в AHK массивы, это вроде как объекты, для таких - "[]" объектов я использую Loop, а для таких - "{}" For-loop, просто чтобы разделять понятия, для себя.

7

Re: AHK: Сравнение переменной с масивом

KusochekDobra пишет:

для таких - "[]" объектов я использую Loop

Это не всегда корректно, один из ключей может быть удалён без смещения остальных, а нам, к примеру, нужно найти ключ, равный пустому значению, в этом случае ваш код даст ложноположительный результат. For-loop лучше использовать всегда.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8

Re: AHK: Сравнение переменной с масивом

Спасибо

9

Re: AHK: Сравнение переменной с масивом

teadrinker пишет:
KusochekDobra пишет:

для таких - "[]" объектов я использую Loop

Это не всегда корректно, один из ключей может быть удалён без смещения остальных, а нам, к примеру, нужно найти ключ, равный пустому значению, в этом случае ваш код даст ложноположительный результат. For-loop лучше использовать всегда.

Благодарю! Весьма уместно, хотя не приходит на ум ни одного примера. Подскажите пожалуйста, как можно удалить из такого массива ключ, чтобы его значение осталось прежним, от чего его ёмкость не поменяется и для чего в нём искать ключ с пустым значением, если доступ к его элементам априори по индексу?

10

Re: AHK: Сравнение переменной с масивом

Наверное подойдет такой пример:

teadrinker пишет:

нужно найти ключ, равный пустому значению, в этом случае ваш код даст ложноположительный результат

arr := [,""]
var := ""
Loop,% arr.Length()
   if (arr[ A_Index ] == var)
      msgbox % A_Index
msgbox For-loop
For index, value in arr
   if (value = var)
      msgbox % index

11

Re: AHK: Сравнение переменной с масивом

teadrinker пишет:

... один из ключей может быть удалён без смещения остальных, а нам, к примеру, нужно найти ключ, равный пустому значению...

Как подумалось мне об этом, что некоторый ключ из линейного массива "[]" может быть удалён, при том так, что его имя теперь не числовое значение, а пустое (""), но при этом, его ёмкость осталась прежней.

12

Re: AHK: Сравнение переменной с масивом

arr := [1, "", 3, ""]
arr.Delete(2)
var := ""

MsgBox, % VarInArr(var, arr)  ; возвращает 2

for k in arr
   MsgBox, % k

; как видим, ключа "2" не существует

VarInArr(var, arr) {
   Loop,% arr.Length()
      if (arr[ A_Index ] == var)
         return A_Index
   return 0
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Сравнение переменной с масивом

Это я понимаю, но целесообразность Delete(), для меня, очень спорна в отношении линейного массива, да и в справке намекают о применительной способности этого метода, подразумевая объект:

Removes key-value pairs from an object.

Я же говорю, что стараюсь разделять эти понятия, где массив это - [], а объект - {}, что само по себе подразумевает разный подход. Как, например, рубашка и куртка, или носки и ботинки - в этих парах, каждый из объектов имеет сильно схожие функциональные особенности, однако же применяются только для своих целей. Можно конечно и куртку на голое тело одевать, а рубашку сверху, или в одних носках гонять по сугробам зимой, но я это трактую как применение Delete() для [] - спорно.

Но раз кто-то может себе такое позволить, то замечание весьма уместно, за что уже успел откланяться.

14

Re: AHK: Сравнение переменной с масивом

Это я понимаю, но целесообразность Delete(), для меня, очень спорна в отношении линейного массива

Простой пример — собираем в массив хэндлы каких-либо окон. Когда окно уничтожается, имеет смысл ключ с ним удалять, а если мы хотим, чтобы оставшиеся хэндлы продолжали находиться на своих местах — будем удалять с помощью Delete().

KusochekDobra пишет:

Я же говорю, что стараюсь разделять эти понятия, где массив это - [], а объект - {}

В некоторых случаях в этом есть смысл, в некоторых нет. Что скажете о массиве, индексы которого начинаются с 0? В какую категорию он должен войти?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: Сравнение переменной с масивом

Скажу, что свой путь в программировании начинал с материала сразу трёх учебников по C# - это "Базовый курс по C# от 2008г", Троелсен "C# 4.0" и Шидлт, с похожим названием. Все они объясняли по разному, в немного разном порядке, но одинаковый материал, что давало возможность смотреть на него с разных ракурсов глазами человека, не имеющего абсолютно никакой сравнительной базы. Как если бы ходить учился. Исходя из усвоенного, подразумеваю массивы с индексом начинающимся от нуля - фундаментальным представлением массива. Правда, в C# все переменные строго типизированы и в такой массив нельзя помещать строки и числа, но это позволяют делать коллекции. В чём-то, я проецирую усвоенное, на практику в AHK, считая полезным порядок из материала учебников, перенятый не абсолютно, но до какой-то меры. Например, for - это цикл со счётчиком, имеющим свою аналогию в loop. Все примеры с массивами, в книгах, были с участием только этого цикла, тогда как для коллекций, наследующих энумератор от базового прототипа object, применялся foreach, перебирающий свойства аналогично "for k, v in obj". Некоторые такие детали прочно обосновались в голове, но я ещё не испытывал каких-либо сложностей в связи с этим.

То, о чём последние сообщения этой беседы, лишь вопрос личных предпочтений и раз о вкусах не спорят, то знать их, как минимум, полезно.
Я, например, предпочту собрать хендлы окон в "коллекцию" {} с именованными полями, если для меня важно обращаться к ним по именам, раз по определению они должны быть константны, или буду рассматривать такой объект, набранный через Push() - как {}, потому как на это прямо указывает семантика самого определения и последнее, не отменяет того, что такой объект заблаговременно подразумевается как {}, ещё на этапе написания, что в свою очередь продолжает разделять понятия [] и {}, в моём понимании.

16

Re: AHK: Сравнение переменной с масивом

Уважаю и даже разделяю ваше желание следовать определённой семантике, но код при этом предпочтительно должен оставаться корректным в контексте того ЯП, в котором он используется. Особенно, если выложен в паблик.

KusochekDobra пишет:

целесообразность Delete(), для меня, очень спорна в отношении линейного массива, да и в справке намекают о применительной способности этого метода, подразумевая объект

У вас небольшая путаница с понятием "объект". В AHK объект — это общее название для всех возможных объектов. [] — это "простой" или "линейный" массив, {} — ассоциативный массив. Но по сути оба являются ассоциативными массивами, первый — частный случай второго. О применительной способности — смотрите дальше, там в примере именно [].

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17

Re: AHK: Сравнение переменной с масивом

Благодарю за совет! Постараюсь соответствовать.

Путаницы нет. Уверяю Вас, что понимаю эту механику ровно так же, как Вы и описали. Лишь акцентирую внимание на том, что для себя, подразумеваю различный подход, как к концепциям массива и списка. Именно это может вызывать ощущение такой коллизии, но то, лишь ощущение.

18 (изменено: stealzy, 2018-04-29 18:26:10)

Re: AHK: Сравнение переменной с масивом

seriyforum пишет:

Почитал, но так и не нашёл решения.

Object.HasKey(Key)

19

Re: AHK: Сравнение переменной с масивом

А причём тут HasKey? Мы, вроде, о значениях ключей говорим, а не об их названиях. Или я неверно понял задачу.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

20 (изменено: stealzy, 2018-04-30 01:23:30)

Re: AHK: Сравнение переменной с масивом

Ох, попутал. А ведь я даже писал велосипед для этой проблемы полтора года назад:
https://autohotkey.com/boards/viewtopic … mp;t=23286
Продублирую код:

; Ф-ия возвращает индекс первого элемента с искомым значением, если таковой есть в массиве.
; Если значение в массиве не найдено возвращает 0.
; Опциональный параметр - номер индекса, с которого ведется поиск (только для простых массивов с последовательным неизмененным индексом. Если применялся .Delete(), то применять параметр нельзя)

indexOf(Arr, needle, fromIndex:=1) {
	if (fromIndex = 1) {
		for index, value in Arr
			if (value = needle)
				return index
	} else
		loop % Arr.MaxIndex() - fromIndex + 1
			if (needle = Arr[A_Index + fromIndex - 1])
				return A_Index + fromIndex - 1
	return false
}

UPD: В свете того, что в AHK нет простых массивов, код надо безопасно переделать.

21 (изменено: stealzy, 2018-04-30 02:01:27)

Re: AHK: Сравнение переменной с масивом

Предлагаю так:

arr := {5: 1, e: 2, "": 3, 0:2}
if HasValue(2, arr)
	MsgBox % "Ключей с искомым значением найдено - " HasValue(2, a).Length() ",`nпервый по порядку ключ - " HasValue(2, a).1

HasValue(var, arr) {
	arrOfKeys := {}
	for key, value in arr
		if (value == var)
			arrOfKeys.Push(key)
	return (arrOfKeys.Length() = 0) ? false : arrOfKeys
}

Если значения нет, возвращает 0, иначе массив ключей, имеющих искомое значение.