Что нового

Удаление пустых строк из массива

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
AutoIt: 3.3.6.1+
Версия: 1.1

Категория: массивы

Описание: Функция на основе идеи Yashied`a

Код:
; #FUNCTION# =================================================================================================
; Name...........: _ArrayClearEmpty
; Description ...: Удаляет из массива: 1-размерного пустые строки;
;                                      2-размерного пустые строки по индексу колонки.
; Syntax.........: _ArrayClearEmpty(ByRef $a_Array, $i_SubItem = 0, $i_Start = 0)
; Parameters ....: $a_Array - массив, в котором удаляются пустые строки.
;                  |$i_SubItem  - индекс колонки (у 2-размерного массива)по которой идет поиск пустых строк,
;                  по умолчанию - первая колонка.
;                  |$i_Start - индекс строки начала поиска пустых строк, по умолчанию - 0(первая строка).
; Return values .: Успех - 1 и @error = 0 и
;                  @extended - количество удаленных пустых строк.
;                  Неудача - 0 и @error = :
;                  | 1 - $a_Array не является массивом или его размерность больше 2
;                  | 2 - в 1-размерном массиве все строки пустые (см. Remarks);
;                        в 2-размерном массиве все строки пустые по индексу колонки $i_SubItem (см. Remarks).
; Author ........: madmasles (функция), идея: Yashied http://autoit-script.ru/index.php?topic=1905.msg13688#msg13688
; Remarks .......: если $i_Start > 0 и все строки, начиная с $i_Start пустые, то вернет массив со строками
;                  с 0 по $i_Start - 1 и @error = 0.
;                  Числовое значение строки 0 не считается пустым значением.
; ============================================================================================================


Код/Пример:
Код:
#include <Array.au3>

Opt('MustDeclareVars', 1)

Dim $array_1[1000]
For $i = 0 To 999
	If Not Mod($i, 100) Then
		$array_1[$i] = ''
	Else
		$array_1[$i] = $i
	EndIf
Next

Dim $array_2[1000][2]
For $i = 0 To 999
	If Not Mod($i, 100) Then
		$array_2[$i][0] = ''
	Else
		$array_2[$i][0] = $i
	EndIf
	If Not Mod($i, 150) Then
		$array_2[$i][1] = ''
	Else
		$array_2[$i][1] = $i
	EndIf
Next

_ArrayDisplay($array_1, 'До - 1')

_ArrayClearEmpty($array_1, 0, 1)
;чистим 1-размерный массив от пустых строк начиная с 1-ой строки.
If Not @error Then
	_ArrayDisplay($array_1, 'После - 1, пустых: ' & @extended)
Else
	MsgBox(16, 'Error', @error)
EndIf
_ArrayClearEmpty($array_1)
;чистим весь 1-размерный массив от пустых строк.
If Not @error Then
	_ArrayDisplay($array_1, 'После - 1, пустых: ' & @extended)
Else
	MsgBox(16, 'Error', @error)
EndIf

_ArrayDisplay($array_2, 'До - 2')

_ArrayClearEmpty($array_2, 0, 1)
;чистим 2-размерный массив от пустых строк по первой колонке начиная с 1-ой строки.
If Not @error Then
	_ArrayDisplay($array_2, 'После - 2 - 0, пустых: ' & @extended)
Else
	MsgBox(16, 'Error', @error)
EndIf

_ArrayClearEmpty($array_2, 1)
;чистим весь 2-размерный массив от пустых строк по второй колонке
If Not @error Then
	_ArrayDisplay($array_2, 'После - 2 - 1, пустых: ' & @extended)
Else
	MsgBox(16, 'Error', @error)
EndIf


; #FUNCTION# =================================================================================================
; Name...........: _ArrayClearEmpty
; Description ...: Удаляет из массива: 1-размерного пустые строки;
;                                      2-размерного пустые строки по индексу колонки.
; Syntax.........: _ArrayClearEmpty(ByRef $a_Array, $i_SubItem = 0, $i_Start = 0)
; Parameters ....: $a_Array - массив, в котором удаляются пустые строки.
;                  |$i_SubItem  - индекс колонки (у 2-размерного массива)по которой идет поиск пустых строк,
;                  по умолчанию - первая колонка.
;                  |$i_Start - индекс строки начала поиска пустых строк, по умолчанию - 0(первая строка).
; Return values .: Успех - 1 и @error = 0 и
;                  @extended - количество удаленных пустых строк.
;                  Неудача - 0 и @error = :
;                  | 1 - $a_Array не является массивом или его размерность больше 2
;                  | 2 - в 1-размерном массиве все строки пустые (см. Remarks);
;                        в 2-размерном массиве все строки пустые по индексу колонки $i_SubItem (см. Remarks).
; Author ........: madmasles (функция), идея: Yashied http://autoit-script.ru/index.php?topic=1905.msg13688#msg13688
; Remarks .......: если $i_Start > 0 и все строки, начиная с $i_Start пустые, то вернет массив со строками
;                  с 0 по $i_Start - 1 и @error = 0.
;                  Числовое значение строки 0 не считается пустым значением.
; ============================================================================================================
Func _ArrayClearEmpty(ByRef $a_Array, $i_SubItem = 0, $i_Start = 0)
	If Not IsArray($a_Array) Or UBound($a_Array, 0) > 2 Then Return SetError(1, 0, 0)

	Local $i_Index = -1
	Local $i_UBound_Row = UBound($a_Array, 1) - 1
	Local $i_UBound_Column = UBound($a_Array, 2) - 1
	Local $a_TempArray[1]
	If $i_UBound_Column = -1 Then $i_UBound_Column = 0
	If $i_SubItem > $i_UBound_Column Then $i_SubItem = 0
	If $i_Start < 0 Or $i_Start > $i_UBound_Row Then $i_Start = 0

	Switch $i_UBound_Column + 1
		Case 1
			ReDim $a_TempArray[$i_UBound_Row + 1]
			If $i_Start Then
				For $i = 0 To $i_Start - 1
					$a_TempArray[$i] = $a_Array[$i]
				Next
				$i_Index = $i_Start - 1
			EndIf
			For $i = $i_Start To $i_UBound_Row
				If String($a_Array[$i]) Then
					$i_Index += 1
					$a_TempArray[$i_Index] = $a_Array[$i]
				EndIf
			Next
			If $i_Index > -1 Then
				ReDim $a_TempArray[$i_Index + 1]
			Else
				Return SetError(2, 0, 0)
			EndIf
		Case Else
			ReDim $a_TempArray[$i_UBound_Row + 1][$i_UBound_Column + 1]
			If $i_Start Then
				For $i = 0 To $i_Start - 1
					For $j = 0 To $i_UBound_Column
						$a_TempArray[$i][$j] = $a_Array[$i][$j]
					Next
				Next
				$i_Index = $i_Start - 1
			EndIf
			For $i = $i_Start To $i_UBound_Row
				If String($a_Array[$i][$i_SubItem]) Then
					$i_Index += 1
					For $j = 0 To $i_UBound_Column
						$a_TempArray[$i_Index][$j] = $a_Array[$i][$j]
					Next
				EndIf
			Next
			If $i_Index > -1 Then
				ReDim $a_TempArray[$i_Index + 1][$i_UBound_Column + 1]
			Else
				Return SetError(2, 0, 0)
			EndIf
	EndSwitch
	$a_Array = $a_TempArray
	Return SetExtended($i_UBound_Row - $i_Index, 1)
EndFunc   ;==>_ArrayClearEmpty

История версий: второй релиз

Источник: Удаление пустых строк из массива

Автор(ы): madmasles (функция), идея Yashied.
 
Автор
madmasles

madmasles

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

Dim $aArray[10000]
For $i = 0 To 9999
	If Not Mod($i, 100) Then
		$aArray[$i] = ''
	Else
		$aArray[$i] = $i
	EndIf
Next
_ArrayDisplay($aArray, 'До')

$iStart = TimerInit()
$aArray_Cl = _ArrayClearEmpty($aArray)
$iCount = @extended
$iTime_1 = TimerDiff($iStart)
$iTime = StringFormat('Time: %.2f msec', $iTime_1)
If Not @error Then
	_ArrayDisplay($aArray_Cl, 'После, пустых: ' & $iCount)
	MsgBox(64, 'Info', $iTime)
Else
	MsgBox(16, 'Error', @error)
EndIf
;==================
;автор XpycT: http://autoit-script.ru/index.php?topic=4496.msg32648#msg32648
$iStart_1 = TimerInit()
For $i = UBound($aArray, 1) - 1 To 0 Step -1
	If $aArray[$i] = "" Then _ArrayDelete($aArray, $i)
Next
$iTime_2 = TimerDiff($iStart_1)
$iTime = StringFormat('Time: %.2f msec', $iTime_2)
_ArrayDisplay($aArray, $iTime)
;===================

MsgBox(64, 'Info', 'Разница: ' & StringFormat('%.2f msec', $iTime_2 - $iTime_1) & @LF & _
		'Или в : ' & StringFormat('~%02d раз', $iTime_2 / $iTime_1))
;===================

Func _ArrayClearEmpty($a_Array, $i_SubItem = 0, $i_Start = 0)
	If Not IsArray($a_Array) Or UBound($a_Array, 0) > 2 Then Return SetError(1, 0, 0)

	Local $i_Index = -1
	Local $i_UBound_Row = UBound($a_Array, 1) - 1
	Local $i_UBound_Column = UBound($a_Array, 2) - 1

	If $i_UBound_Column = -1 Then $i_UBound_Column = 0
	If $i_SubItem > $i_UBound_Column Then $i_SubItem = 0
	If $i_Start < 0 Or $i_Start > $i_UBound_Row Then $i_Start = 0

	Switch $i_UBound_Column + 1
		Case 1
			Dim $a_TempArray[$i_UBound_Row + 1]
			If $i_Start Then
				For $i = 0 To $i_Start - 1
					$a_TempArray[$i] = $a_Array[$i]
				Next
				$i_Index = $i_Start - 1
			EndIf
			For $i = $i_Start To $i_UBound_Row
				If String($a_Array[$i]) Then
					$i_Index += 1
					$a_TempArray[$i_Index] = $a_Array[$i]
				EndIf
			Next
			If $i_Index > -1 Then
				ReDim $a_TempArray[$i_Index + 1]
			Else
				Return SetError(2, 0, 0)
			EndIf
		Case 2
			Dim $a_TempArray[$i_UBound_Row + 1][$i_UBound_Column + 1]
			If $i_Start Then
				For $i = 0 To $i_Start - 1
					For $j = 0 To $i_UBound_Column
						$a_TempArray[$i][$j] = $a_Array[$i][$j]
					Next
				Next
				$i_Index = $i_Start - 1
			EndIf
			For $i = $i_Start To $i_UBound_Row
				If String($a_Array[$i][$i_SubItem]) Then
					$i_Index += 1
					For $j = 0 To $i_UBound_Column
						$a_TempArray[$i_Index][$j] = $a_Array[$i][$j]
					Next
				EndIf
			Next
			If $i_Index > -1 Then
				ReDim $a_TempArray[$i_Index + 1][$i_UBound_Column + 1]
			Else
				Return SetError(2, 0, 0)
			EndIf
	EndSwitch
	Return SetError(0, $i_UBound_Row - $i_Index, $a_TempArray)
EndFunc   ;==>_ArrayClearEmpty
 
Автор
madmasles

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Поправил код функции. Версия 1.1.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Tempo
а именно про строки и речь
нужно править код, добавить проверку типа значения в индексе массива
примерно так
Код:
Switch VarGetType($a_Array[$i])
	Case 'Array'
		$i_Index += 1
		$a_TempArray[$i_Index] = $a_Array[$i]
	Case 'String'
		If String($a_Array[$i]) Then
			$i_Index += 1
			$a_TempArray[$i_Index] = $a_Array[$i]
		EndIf
EndSwitch
 
Верх