Что нового

удаление элемента в цикле

running-frag

why me?
Сообщения
441
Репутация
60
Код:
#include <Array.au3>
Dim $_arr[6]

$_arr[0] = 5
$_arr[1] = "~"
$_arr[2] = "†"
$_arr[3] = "a"
$_arr[4] = "B"
$_arr[5] = "C"

For $i = 1 To $_arr[0]
	$_result = StringRegExp ($_arr[$i], "[a-zA-Z0-9]", 0)
	
	ConsoleWrite ($i &". - ")
	
    If $_result Then
		ConsoleWrite (" well done"&@CR)
	Else
		_ArrayDelete ($_arr, $i)
		$_arr[0] -= 1
		$i -= 1
		ConsoleWrite (" deleted done"&@CR)
	EndIf
	
Next

_ArrayDisplay ($_arr)


Как реализовать пробег по всем элементам пробег, с учётом удаление элемента. Т.е. общее количество элементом может уменьшаться по ходу прохода по циклу.

ps: код выше с ошибкой
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
ну там через строку, а если через цикл For сделать, как это будет выглядеть?
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Код:
#include <Array.au3>
Dim $_arr[6]

$_arr[0] = 5
$_arr[1] = "~"
$_arr[2] = "†"
$_arr[3] = "a"
$_arr[4] = "B"
$_arr[5] = "C"

For $i = 1 To $_arr[0]
	ConsoleWrite ("count is "& $_arr[0] &" and $i is "& $i &@CR)
	$_result = StringRegExp ($_arr[$i], "[a-zA-Z0-9]", 0)
	
	ConsoleWrite ($i &". - "&$_arr[$i])
	
    If $_result Then
		ConsoleWrite (" well done"&@CR)
	Else
		ConsoleWrite (" deleted done"&@CR)
		_ArrayDelete ($_arr, $i)
		$_arr[0] -= 1
		$i -= 1
		
	EndIf
	
	If $i = $_arr[0] Then ExitLoop
Next

_ArrayDisplay ($_arr)


Вот вроде рабочий но мне сильно не нравится строка
Код:
$i -= 1

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

Или может у кого есть другие варианты.

Зачем: Допустим у нас в массиве не одиночные символы, а строка с пробелами и нам нужно "просто удалить" некоторые элементы не трогая остальное.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
running-frag,
Через строку, ИМХО, быстрее.
Код:
#include <Array.au3>

$sText = ''
For $i = 1 To 100
	$sText &= Chr(Random(33, 126, 1))
Next
ConsoleWrite($sText & @LF)

$aText = StringSplit($sText, '')
$sText = ''
_ArrayDisplay($aText, 'Before')

Dim $aTemp[$aText[0] + 1]
For $i = 1 To $aText[0] ;Or For $i = 0 To UBound($aText) - 1
	If StringRegExp($aText[$i], '(?i)[a-z\d]') Then
		$aTemp[0] += 1
		$aTemp[$aTemp[0]] = $aText[$i]
	EndIf
Next
ReDim $aTemp[$aTemp[0] + 1]
$aText = $aTemp
$aTemp = 0
_ArrayDisplay($aText, 'After')
running-frag [?]
Допустим у нас в массиве не одиночные символы, а строка с пробелами и нам нужно "просто удалить" некоторые элементы не трогая остальное
Пример?
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Код:
$_arr[0] = 5
$_arr[1] = "vnw&sld!" 	; неудалять
$_arr[2] = "*"			; удалять
$_arr[3] = "1240 asb"
$_arr[4] = "*&% sajlfg" ; удалять
$_arr[5] = "none"		; неудалять
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
running-frag,
Должен удалить все строки, содержащие символ *, если я правильно Вас понял.
Код:
#include <Array.au3>

$sSymb = '*'
$vTemp = Random(100, 250, 1)
Dim $aText[$vTemp + 1] = [$vTemp]
$vTemp = 0
For $i = 1 To $aText[0]
	$aText[$i] = _RandomText(Random(10, 20, 1))
Next
_ArrayDisplay($aText, 'Before')

Dim $vTemp[$aText[0] + 1]
For $i = 1 To $aText[0]
	;;StringReplace($aText[$i], $sSymb, '');или так
	;;If Not @extended Then
	;If Not StringRegExp($aText[$i], '\Q' & $sSymb & '\E') Then ;или так
	If Not StringInStr($aText[$i], $sSymb) Then;или так
		$vTemp[0] += 1
		$vTemp[$vTemp[0]] = $aText[$i]
	Else
		ConsoleWrite($aText[$i] & @LF)
	EndIf
Next
ReDim $vTemp[$vTemp[0] + 1]
$aText = $vTemp
$vTemp = 0
_ArrayDisplay($aText, 'After')

Func _RandomText($i_Len)
	Local $s_Text
	$i_Len = Int($i_Len)
	If $i_Len < 1 Then Return ''
	For $i = 1 To $i_Len
		$s_Text &= Chr(Random(32, 255, 1))
	Next
	Return $s_Text
EndFunc   ;==>_RandomText


Если в Вашем скрипте из 1-го поста поменять
Код:
;...
For $i = 1 To $_arr[0]
;...
;на
;...
For $i = $_arr[0] To 1 Step -1
;...
;и убрать
;...
$i -= 1
То ошибок не будет.
 

CreatoR

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

Код:
#include <Array.au3>

Dim $_arr[6]

$_arr[0] = 5
$_arr[1] = "~"
$_arr[2] = "†"
$_arr[3] = "a"
$_arr[4] = "B"
$_arr[5] = "C"

$iCount = $_arr[0]

For $i = $_arr[0] To 1 Step -1
	$_result = StringRegExp($_arr[$i], "[a-zA-Z0-9]", 0)
	
	ConsoleWrite(-($i-$iCount-1) & ". - ")
	
	If $_result Then
		ConsoleWrite(" well done" & @CR)
	Else
		_ArrayDelete($_arr, $i)
		$_arr[0] -= 1
		ConsoleWrite(" deleted done" & @CR)
	EndIf
Next

_ArrayDisplay($_arr)
 
Верх