Что нового

Перебор двумерного массива в цикле For In Next

sem0709

Новичок
Сообщения
11
Репутация
1
С одномерным вроде бы всё понятно:

Код:
#include <Array.au3> ;plug working arrays

Local $Array[2] = ["one", "two"]

   For $Element In $Array
	  MsgBox(0, "Header", $Element)
   Next


А как используя тот же цикл перебрать дву- и более -мерный массив?
Если так, то совсем не заходит в цикл:

Код:
#include <Array.au3> ;plug working arrays

Local $Array[2][2] = [["one", "two"],["three", "four"]]

   For $Element In $Array
	  MsgBox(0, "Header", $Element)
   Next
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Код:
#include <Array.au3> ;plug working arrays

Local $Array[2][2] = [["one", "two"],["three", "four"]]

   For $i=0 to 1
	   For $j=0 to 1
          MsgBox(0, "Header", $Array[$i][$j])
	   Next
   Next
 
Автор
S

sem0709

Новичок
Сообщения
11
Репутация
1
ra4o сказал(а):
Код:
#include <Array.au3> ;plug working arrays

Local $Array[2][2] = [["one", "two"],["three", "four"]]

   For $i=0 to 1
	   For $j=0 to 1
          MsgBox(0, "Header", $Array[$i][$j])
	   Next
   Next

Вы используете For To Next.
Вопрос задан про For In Next... меня интересует перебор именно ЭЛЕМЕНТ из КОЛЛЕКЦИИ.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Код:
#include <Array.au3> ;plug working arrays
Dim $Array[2]
Local $Array1[2]=["one", "two"]
Local $Array2[2]=["three", "four"]
$array[0]=$Array1
$array[1]=$Array2
   For $i in $array
	   For $j in $i
         MsgBox(0, "Header", $j)
	   Next
   Next
 
Автор
S

sem0709

Новичок
Сообщения
11
Репутация
1
ra4o сказал(а):
Код:
#include <Array.au3> ;plug working arrays
Dim $Array[2]
Local $Array1[2]=["one", "two"]
Local $Array2[2]=["three", "four"]
$array[0]=$Array1
$array[1]=$Array2
   For $i in $array
	   For $j in $i
         MsgBox(0, "Header", $j)
	   Next
   Next

Любопытно, конечно, массивы в массиве...)
Но если элементов больше двух, сотни, тысячи. Мне тогда нужно будет использовать другие циклы для заполнения.
К тому же я использую IniReadSection() который мне сразу возвращает двумерный массив, да ещё и пару ключ=значение, которую мне при условии нужно будет изменить.

Код:
For $Section In IniReadSectionNames($FileSettings)

	  $elements = IniReadSection($FileSettings, $Section) ; ХОЧУ ИЗБЕЖАТЬ ВОТ ЭТОТ МОМЕНТ И СРАЗУ ПЕРЕБИРАТЬ ЭЛЕМЕНТЫ В ЦИКЛЕ
	  
	  For $i = 1 To UBound($elements) - 1 Step 2
		 If $elements[$i][1] == 0 And $elements[$i + 1][1] == 0 Then
			$MousePos = MouseGetPos()
			IniWrite($FileSettings, $Section, $elements[$i][0], $MousePos[0])
			IniWrite($FileSettings, $Section, $elements[$i + 1][0], $MousePos[1])
			ExitLoop 2
		 EndIf
	  Next

   Next
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
пару ключ=значение, которую мне при условии нужно будет изменить
Вы читали справку ? Это вас не смущает ?
Массивы AutoIt внутри выражения For...In доступны только для чтения. Присвоить значение переменной внутри выражения For...In возможно, однако, это изменение никак не скажется на самом массиве. Чтобы иметь возможность модифицировать содержание массива используйте цикл For...To.
Ах, да, не вникал в Ваш скрипт , Вы меняете не сам массив, а сразу значение ключа в ini файле.. Только не пойму, каким образом Вы хотите упростить цикл заменив For to на For in ?
 
Автор
S

sem0709

Новичок
Сообщения
11
Репутация
1
ra4o сказал(а):
Массивы AutoIt внутри выражения For...In доступны только для чтения.

Не читал, но собственно только чтение и нужно.
Я получаю из файла двумерный массив ключ=значение, перебираю его, ищу что нужно, при необходимости меняю значение ключа в ФАЙЛЕ.
Сам массив используется только для чтения, записываю уже в файл.

Из примера сверху:
Я перебираю в цикле секции ini файла, для каждой секции перебираю параметры(ключ=значение)- вложенные циклы.
С секциями проблем нет, потому что функция IniReadSectionNames() возвращает одномерный массив, а вот при чтении параметров IniReadSection() уже возвращается двумерный массив (ключ=значение). Его с помощью For In Next и хочу перебрать.
На самом деле всё работает и так, но меня смущает ВОЗМНОЖНО, которую можно избежать, "лишняя" строка $elements = IniReadSection($FileSettings, $Section)
, и так как, я только начал изучать Autoit меня интересует возможность перебора двумерных массивов в цикле Для Каждого.. Конечно, благодаря Вам знаю, что только для чтения.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
"лишняя" строка $elements = IniReadSection($FileSettings, $Section)
без этой строки Вы ведь не получите свой двумерный массив с ключами и значениями, другое дело - какой способ самый быстрый в поиске нужных значений... Из двумерного массива можно легко сделать одномерный, удалив "лишнюю" колонку функцией "_ArrayColDelete" и дальше работать с "For ..in", можно искать нужные значения в массиве при помощи функции "_ArraySearch"... вариантов много...
 
Автор
S

sem0709

Новичок
Сообщения
11
Репутация
1
ra4o сказал(а):
"лишняя" строка $elements = IniReadSection($FileSettings, $Section)
без этой строки Вы ведь не получите свой двумерный массив с ключами и значениями, другое дело - какой способ самый быстрый в поиске нужных значений... Из двумерного массива можно легко сделать одномерный, удалив "лишнюю" колонку функцией "_ArrayColDelete" и дальше работать с "For ..in", можно искать нужные значения в массиве при помощи функции "_ArraySearch"... вариантов много...

Если перебирать двумерный массив For In Next тогда можно, сразу коллекцию в цикл включить.

То есть можно заключить, что перебор For In Next двумерных массивов в Autoit не предусмотрен ?
 
A

Alofa

Гость
sem0709 сказал(а):
... меня интересует перебор именно ЭЛЕМЕНТ из КОЛЛЕКЦИИ.
sem0709 сказал(а):
... тогда можно, сразу коллекцию в цикл включить.
Про какого рода коллекции идет речь? Не путайте пожалуйста понятия COM и массивы.

А так не сойдет:
OffTopic:
Код:
$FileSettings = 'C:\WindowsWin.ini'
$MousePos = MouseGetPos()
$sText = FileRead($FileSettings)
; Смотрите в справке последний параметр функции StringRegExpReplace()
$sText = StringRegExpReplace($sText, '\R\h*(0\s*=\s*0)\h*', @CRLF & $MousePos[0] & ' = ' & $MousePos[1], 0)
$hFile = FileOpen($FileSettings, 2)
FileWrite($hFile, $sText)
FileClose($hFile)
 
Автор
S

sem0709

Новичок
Сообщения
11
Репутация
1
Alofa сказал(а):
sem0709 сказал(а):
... меня интересует перебор именно ЭЛЕМЕНТ из КОЛЛЕКЦИИ.
sem0709 сказал(а):
... тогда можно, сразу коллекцию в цикл включить.
Про какого рода коллекции идет речь? Не путайте пожалуйста понятия COM и массивы.

А так не сойдет:

А причем тут COM ? Вы первый пост читал, вместе с темой ? Требуется перебрать массив, то есть коллекцию элементов. По теме: перебрать двумерный массив циклом For In Next. Так что, скорее всего вы сами что-то путаете.
В свете описаного, совсем не понимаю как могу применить к теме Ваш офтоп...
 

joiner

Модератор
Локальный модератор
Сообщения
3,497
Репутация
619
For...In
в основном и зачастую применяется для перечисления коллекции объекта - COM(смотри пример в справке)
и предназначен только для работы с одномерными массивами(смотри актуальную справку)
не вижу причины для упорства применить именно этот метод получения данных из массива, тем более он не одномерный
есть плюс у этого метода - если переменная не массив, то скрипт не вывалится с ошибкой
 
Автор
S

sem0709

Новичок
Сообщения
11
Репутация
1
joiner сказал(а):
For...In
в основном и зачастую применяется для перечисления коллекции объекта - COM(смотри пример в справке)
и предназначен только для работы с одномерными массивами(смотри актуальную справку)
не вижу причины для упорства применить именно этот метод получения данных из массива, тем более он не одномерный
есть плюс у этого метода - если переменная не массив, то скрипт не вывалится с ошибкой

Предпочитаю доверять двум справкам:
в комплекте со средой (3.3.14.2) и так как она английская,
юзаю русскую на этом сайте: autoit-script.ru/autoit3_docs/keywords/ForInNext.htm
Это самые актуальные или есть ещё ?
Честно, по массивам справка дурацкая, разбросаны по всем разделам. Как объявлять в одном разделе, перебирать в другом, манипуляции с массивом в третьем.
Кстати, по ссылке сказано, что этот оператор циклов используется "Перечисляет элементы в коллекции объекта или МАССИВА".
Что цикл используется только для одномерного массива можно увидеть из примеров, но это не значит, что нельзя и для других...

В вопросе нет принципиальной разницы в использовании именно этого способа перебора.
Это простой, обычный вопрос, можно или не можно перебрать двумерный массив в For In.
Без подоплёки, лишь для общего развития и понимания. Ну вот такой я дотошный)
 

joiner

Модератор
Локальный модератор
Сообщения
3,497
Репутация
619
русскоязычная только для старой версии и есть ошибки в переводе
читать справку по версии языка, которая используется. я лучше машинный перевод сделаю, так как сам не ахти в английском
Справка по AutoIT хорошо написана. Но всем не угодишь. А про массивы написано в разделе - Описание языка->Переменные.
В остальных разделах упоминается лишь касательно описываемой функции. Так что, все описано подробно

sem0709 [?]
"Перечисляет элементы в коллекции объекта или МАССИВА".
я по этому моменту ясно написал:
joiner [?]
в основном и зачастую
то есть, часто используют в перечислении элементов коллекции объекта. это не правило, просто что встречается в примерах именно в этом использовании

насчет дотошности, то это вполне хорошее качество :smile:
 
Автор
S

sem0709

Новичок
Сообщения
11
Репутация
1
Считаю тему исчерпанной, не вижу смысла увеличивать трэд...
Всем спасибо за ответы... тема решена.
 
Верх