Что нового

Вложенный перебор двух массивов. Проблемы с выходом из перебора

Suppir

Продвинутый
Сообщения
967
Репутация
62
Изначальный код:

Код:
For $x = 1 to Ubound($gar) - 1
		$err = 1
		For $i = 1 to UBound($sin, 1) - 1 
			if StringRegExp($gar[$x], "^" & $sin[$i][0]) Then
				_ArrayAdd($garReady, $gar[$x])
				$err = 0
			EndIf
		Next
		if $err = 0 Then _ArrayAdd($garUndef, $gar[$x])
	Next


Есть массивы $gar[] и $sin[][]

Нужно:

перебирая каждый элемент массива $gar
перебирать каждый элемент массива $sin
если строка $sin[$i][0] содержится в $gar[$x],
то занести $gar[$x] в массив $garReady.
а если для элемента $gar[$x] не найдено совпадение ни с одним элементом $sin,
то занести $gar[$x] в массив $garUndef.

Почему-то в коде выше создается куча дублей в массиве $garReady :(
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
А зачем везде где попало ляпать StringRegExp...? StringInStr() здесь более уместен.
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
Массив $sin состоит из регулярных выражений ($sin[$i][0] - шаблон поиска, $sin[$i][1] - шаблон замены)
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Может быть

Код:
If $err Then _ArrayAdd($garUndef, $gar[$x])


вместо

Код:
If $err = 0 Then _ArrayAdd($garUndef, $gar[$x])
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
Тьфу, и правда!

Еще вопрос прямо в коде:

Код:
For $x = 1 to Ubound($gar) - 1
        $err = 1
        For $i = 1 to UBound($sin, 1) - 1 
            if StringRegExp($gar[$x], "^" & $sin[$i][0]) Then # если вот здесь совпадение найдено, 
                _ArrayAdd($garReady, $gar[$x]) 
                $err = 0 # то каким образом отсюда...
            EndIf
        Next 
        # сразу перейти на это место? Чтобы не делать лишних переборов
        if $err = 0 Then _ArrayAdd($garUndef, $gar[$x]) 
    Next
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
ExitLoop

А лучше так:

Код:
For $x = 1 To UBound($gar) - 1
	For $i = 1 To UBound($sin) - 1
		If StringRegExp($gar[$x], "^" & $sin[$i][0]) Then
			_ArrayAdd($garReady, $gar[$x])
			ContinueLoop 2
		EndIf
	Next
	_ArrayAdd($garUndef, $gar[$x])
; ContinueLoop 2 попадает сюда
Next
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
Yashied, а после ContinueLoop 2 куда мы попадем:

в начало нового цикла "For $x = 1 To UBound($gar) - 1"
или в место _ArrayAdd($garUndef, $gar[$x])

?
 

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
А зачем нужно два цикла ?
Разве нельзя так ?
Код:
#include <Array.au3>   
Dim	$aGar[5]=[4,"Один","Два","Три","Четыре"]
$sGar=_ArrayToString($aGar, "|" ,1)	
Dim	$aSin[5]=[4,"ААА","БББ","Три","ВВВ"]
Dim $aGarReady[1]
Dim $aGarUndef[1]	
For $i = 1 to UBound($aSin) - 1 
     If StringRegExp($sGar, $aSin[$i]) =1 Then 
           _ArrayAdd($aGarReady, $aSin[$i])
     Else
	 _ArrayAdd($aGarUndef, $aSin[$i])
     EndIf
 Next
 _ArrayDisplay($aGarReady)
_ArrayDisplay($aGarUndef)

Я правда взял одинарные массивы (для простоты ) ,но это сути не меняет
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
gregaz, у массивов разное количество элементов.

Yashied, мне почему-то казалось, что при continueLoop 2 будет включена следующая итерация второго внешнего цикла. Т.е. _ArrayAdd($garUndef, $gar[$x]) не сработает.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
Yashied [?]
См. выше, я показал
Это путает, в этом цикле переход будет в начало, т.е так:

Код:
For $x = 1 To UBound($gar) - 1
    ; ContinueLoop 2 попадает сюда - это означает продолжить цикл верхнего уровня со следующего элемента
    For $i = 1 To UBound($sin) - 1
        If StringRegExp($gar[$x], "^" & $sin[$i][0]) Then
            _ArrayAdd($garReady, $gar[$x])
            ContinueLoop 2
        EndIf
    Next
    _ArrayAdd($garUndef, $gar[$x])
Next



Suppir [?]
мне почему-то казалось, что при continueLoop 2 будет включена следующая итерация второго внешнего цикла. Т.е. _ArrayAdd($garUndef, $gar[$x]) не сработает
Всё верно, так и есть.
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
CreatoR, значит нужно использовать ExitLoop?

Код:
For $x = 1 to Ubound($gar) - 1
		$err = 1
		For $i = 1 to UBound($sin, 1) - 1 
			if StringRegExp($gar[$x], $sin[$i][0]) Then
				_ArrayAdd($garReady, $gar[$x])
				$err = 0
				ExitLoop
			EndIf
		Next
		if $err = 1 Then _ArrayAdd($garUndef, $gar[$x])
	Next



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

Кажется, так заработало.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
CreatoR [?]
Это путает, в этом цикле переход будет в начало...
:blink:

Не в начало, а именно в конец цикла, иначе не будет сравнения с максимальным значением.
 

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Suppir [?]
gregaz, у массивов разное количество элементов.
Ну и что ? Все равно проверяется один (нулевой элемент)
Одинарный массив надо представить в виде элемента выбора (...|...|...)
И производить проверку на присутствие в нулевом элементе массива : $sin[$i][0] любого элемента массива $gar
Приблизительно так :
Код:
$gar=_ArrayToString($gar, "|" ,1)	
For $i = 1 to UBound($sin,1) - 1 
    
    If StringRegExp($sin[$i][0], "(" & $gar & ")" Then ;....
Next
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
gregaz, если одинарный массив представить в виде одной строки, то получится строка в несколько мегабайт :smile: Регулярка подвиснет просто.
Я понял твою идею, но именно в моем случае лучше перебором.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
Yashied [?]
Не в начало, а именно в конец цикла, иначе не будет сравнения с максимальным значением
Для “пользователя” это начало, т.к в конце этот переход уловить нельзя :smile: - Ты поставил коментарий в конце, это всё формальности, с виду кажется что если поставить что то после этой строчки коментария, то оно будет выполнено.
 
Верх