Jump to content

IsArrayEmpty


Recommended Posts

Check if an array is empty.  Feedback welcome :)

$iArray = Get_2d_Array()
;~ $iArray = Get_1d_Array()

$empty = IsArrayEmpty($iArray)

If $empty = 0 Then
    MsgBox(0, "", "Array is not empty")
Else
    MsgBox(0, "", "Array is empty")
EndIf

Func Get_2d_Array()

    Local $array[2][3]

    $array[0][0] = "2"
    $array[0][1] = ""
    $array[0][2] = ""

    $array[1][0] = ""
    $array[1][1] = ""
    $array[1][2] = ""

    Return $array

EndFunc   ;==>Get_2d_Array

Func Get_1d_Array()

    Local $array[3]

    $array[0] = "2"
    $array[1] = ""
    $array[2] = ""

    Return $array

EndFunc   ;==>Get_1d_Array

Func IsArrayEmpty($array)

    $string = _ArrayToString($array)

    $string = StringStripWS($string, 8)
    $string = StringReplace($string, "|", "")

    If $string = "" Then
        Return 1
    Else
        Return 0
    EndIf

EndFunc   ;==>IsArrayEmpty

 

Link to comment
Share on other sites

Posted (edited)

Based on the fact that _ArrayToString() already traverse the entire array to form the string it would be more practical to return false when the first index of array with some data it's encountered. I think it might be faster also but didn't check.

#include <Array.au3>

Local $aData[] = ['', '  ', ' test ', '']

MsgBox(0, '', IsArrayEmpty($aData))

Func IsArrayEmpty(Const ByRef $aArray)
    For $Index = 0 To UBound($aArray) - 1
        If Not StringIsSpace($aArray[$Index]) Then Return False
    Next
    Return True
EndFunc

or

Func IsArrayEmpty(Const ByRef $aArray)
    For $Index = 0 To UBound($aArray) - 1
        If StringIsSpace($aArray[$Index]) Then ContinueLoop
        Return False
    Next
    Return True
EndFunc

 

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

Posted (edited)

It all depends on what you call empty.

Local $a[5] is NOT an empty array: it's an array having 5 rows, each having an empty string (or 0) as content.

Local $a[0] IS an empty array, just like $a[0][3] is empty as well.

If you consider a Map, then Local $m[] is an empty map.

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Here's a complete and robust code to check the content of arrays with a maximum dimension of 10

 

Func IsArrayEmpty(ByRef $aArray, $vEmptyValue = "")

    If Not IsArray($aArray) Then Return SetError(1, 0, Null)

    Local $iDimension = UBound($aArray, 0)
    Switch $iDimension
        Case 1
            For $i = 0 To UBound($aArray) - 1
                If _NotEmpty($aArray[$i], $vEmptyValue) Then Return False
            Next
            Return True
        Case 2
            For $i = 0 To UBound($aArray) - 1
                For $j = 0 To UBound($aArray, 2) - 1
                    If _NotEmpty($aArray[$i][$j], $vEmptyValue) Then Return False
                Next
            Next
            Return True
        Case 3
            For $i = 0 To UBound($aArray) - 1
                For $j = 0 To UBound($aArray, 2) - 1
                    For $k = 0 To UBound($aArray, 3) - 1
                        If _NotEmpty($aArray[$i][$j][$k], $vEmptyValue) Then Return False
                    Next
                Next
            Next
            Return True
        Case 4
            For $i = 0 To UBound($aArray) - 1
                For $j = 0 To UBound($aArray, 2) - 1
                    For $k = 0 To UBound($aArray, 3) - 1
                        For $l = 0 To UBound($aArray, 4) - 1
                            If _NotEmpty($aArray[$i][$j][$k][$l], $vEmptyValue) Then Return False
                        Next
                    Next
                Next
            Next
            Return True
        Case 5
            For $i = 0 To UBound($aArray) - 1
                For $j = 0 To UBound($aArray, 2) - 1
                    For $k = 0 To UBound($aArray, 3) - 1
                        For $l = 0 To UBound($aArray, 4) - 1
                            For $m = 0 To UBound($aArray, 5) - 1
                                If _NotEmpty($aArray[$i][$j][$k][$l][$m], $vEmptyValue) Then Return False
                            Next
                        Next
                    Next
                Next
            Next
            Return True
        Case 6
            For $i = 0 To UBound($aArray) - 1
                For $j = 0 To UBound($aArray, 2) - 1
                    For $k = 0 To UBound($aArray, 3) - 1
                        For $l = 0 To UBound($aArray, 4) - 1
                            For $m = 0 To UBound($aArray, 5) - 1
                                For $n = 0 To UBound($aArray, 6) - 1
                                    If _NotEmpty($aArray[$i][$j][$k][$l][$m][$n], $vEmptyValue) Then Return False
                                Next
                            Next
                        Next
                    Next
                Next
            Next
            Return True
        Case 7
            For $i = 0 To UBound($aArray) - 1
                For $j = 0 To UBound($aArray, 2) - 1
                    For $k = 0 To UBound($aArray, 3) - 1
                        For $l = 0 To UBound($aArray, 4) - 1
                            For $m = 0 To UBound($aArray, 5) - 1
                                For $n = 0 To UBound($aArray, 6) - 1
                                    For $o = 0 To UBound($aArray, 7) - 1
                                        If _NotEmpty($aArray[$i][$j][$k][$l][$m][$n][$o], $vEmptyValue) Then Return False
                                    Next
                                Next
                            Next
                        Next
                    Next
                Next
            Next
            Return True
        Case 8
            For $i = 0 To UBound($aArray) - 1
                For $j = 0 To UBound($aArray, 2) - 1
                    For $k = 0 To UBound($aArray, 3) - 1
                        For $l = 0 To UBound($aArray, 4) - 1
                            For $m = 0 To UBound($aArray, 5) - 1
                                For $n = 0 To UBound($aArray, 6) - 1
                                    For $o = 0 To UBound($aArray, 7) - 1
                                        For $p = 0 To UBound($aArray, 8) - 1
                                            If _NotEmpty($aArray[$i][$j][$k][$l][$m][$n][$o][$p], $vEmptyValue) Then Return False
                                        Next
                                    Next
                                Next
                            Next
                        Next
                    Next
                Next
            Next
            Return True
        Case 9
            For $i = 0 To UBound($aArray) - 1
                For $j = 0 To UBound($aArray, 2) - 1
                    For $k = 0 To UBound($aArray, 3) - 1
                        For $l = 0 To UBound($aArray, 4) - 1
                            For $m = 0 To UBound($aArray, 5) - 1
                                For $n = 0 To UBound($aArray, 6) - 1
                                    For $o = 0 To UBound($aArray, 7) - 1
                                        For $p = 0 To UBound($aArray, 8) - 1
                                            For $q = 0 To UBound($aArray, 9) - 1
                                                If _NotEmpty($aArray[$i][$j][$k][$l][$m][$n][$o][$p][$q], $vEmptyValue) Then Return False
                                            Next
                                        Next
                                    Next
                                Next
                            Next
                        Next
                    Next
                Next
            Next
            Return True
        Case 10
            For $i = 0 To UBound($aArray) - 1
                For $j = 0 To UBound($aArray, 2) - 1
                    For $k = 0 To UBound($aArray, 3) - 1
                        For $l = 0 To UBound($aArray, 4) - 1
                            For $m = 0 To UBound($aArray, 5) - 1
                                For $n = 0 To UBound($aArray, 6) - 1
                                    For $o = 0 To UBound($aArray, 7) - 1
                                        For $p = 0 To UBound($aArray, 8) - 1
                                            For $q = 0 To UBound($aArray, 9) - 1
                                                For $r = 0 To UBound($aArray, 10) - 1
                                                    If _NotEmpty($aArray[$i][$j][$k][$l][$m][$n][$o][$p][$q][$r], $vEmptyValue) Then Return False
                                                Next
                                            Next
                                        Next
                                    Next
                                Next
                            Next
                        Next
                    Next
                Next
            Next
            Return True
        Case Else
            Return SetError(3, 0, Null)
    EndSwitch
    Return True
EndFunc   ;==>IsArrayEmpty

Func _NotEmpty($vData, $vEmptyValue = "")
    If $vData <> $vEmptyValue Then Return True
    Return False
EndFunc   ;==>_NotEmpty

 

Link to comment
Share on other sites

Local $aExampleArray[2][3][4] = [[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]
Local $aExampleArray1[2][3][4] = [[["", "", "", ""], ["", "", "", ""], ["", "", "", ""]], [["", "", "", ""], ["", "", "", ""], ["", "", "", ""]]]

ConsoleWrite("Is aExampleArray empty with 0 as empty value? " & IsArrayEmpty($aExampleArray, 0) & @CRLF)
ConsoleWrite("Is aExampleArray1 empty with empty string as empty value? " & IsArrayEmpty($aExampleArray1, "") & @CRLF)

 

Link to comment
Share on other sites

Posted (edited)

In this topic from some time ago (https://www.autoitscript.com/forum/topic/180468-traversing-array/), we were basically discussing how to traverse all the elements of a generic array whose dimensions are unknown. Well in the last post of that thread I posted a way to achieve that.
Using that function can save "a few" bytes and shorten the function considerably.
You can pass multidimensional arrays and even arrays that contain nested arrays without any problems.
I coded the logic whether to consider an element empty or not empty in the function itself on line 30 of the listing rather than passing it via parameter so as to be able to better customize the criterion.

Func IsArrayEmpty(ByRef $aMyArray)
    If Not IsArray($aMyArray) Then Return SetError(1, 0, -1)
    Local $iDimensions = UBound($aMyArray, 0)
    Local $sArraySubscript = "$aMyArray"
    For $i = 0 To $iDimensions - 1
        $sArraySubscript &= '[$aLoops[' & $i & '][2]]'
    Next
    Local $aLoops[$iDimensions][3]
    For $i = 0 To $iDimensions - 1
        $aLoops[$i][0] = 0
        $aLoops[$i][1] = UBound($aMyArray, $i + 1) - 1
        $aLoops[$i][2] = $aLoops[$i][0]
    Next
    Local $x, $vContent
    Do
        $vContent = Execute($sArraySubscript)

        If IsArray($vContent) Then
            $IsEmpty = IsArrayEmpty($vContent) ; <-- recursive call for nested arrays
        Else
            ; check out your "voidness" logic here
            ; ------------------------------------
            $IsEmpty = ($vContent = '') Or ($vContent = False) Or ($vContent = Null) ; ...... up to you decide
        EndIf

        If Not $IsEmpty Then Return False ; Is not Empty

        $x = UBound($aLoops) - 1
        $aLoops[$x][2] += 1
        While ($aLoops[$x][2] > $aLoops[$x][1])
            $aLoops[$x][2] = $aLoops[$x][0]
            $x -= 1
            If $x < 0 Then ExitLoop
            $aLoops[$x][2] += 1
        WEnd
    Until $x < 0

    Return True ; Is Empty
EndFunc   ;==>IsArrayEmpty

 

Edited by Gianni

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Posted (edited)

@Gianni  Very clever code you made there.  I was not aware of it, thank you for sharing.

I had a bit of a hard time understanding the behavior of $x.  So I changed it (hope you don't mind :sweating:) to make it, IMO, easier to read.

Func IsArrayEmpty(ByRef $aMyArray)
    If Not IsArray($aMyArray) Then Return SetError(1, 0, -1)
    Local $iDimensions = UBound($aMyArray, 0)
    Local $sArraySubscript = "$aMyArray"
    For $i = 0 To $iDimensions - 1
        $sArraySubscript &= '[$aLoops[' & $i & '][1]]'
    Next
    Local $aLoops[$iDimensions][2]
    For $i = 0 To $iDimensions - 1
        $aLoops[$i][0] = UBound($aMyArray, $i + 1)
        $aLoops[$i][1] = 0
    Next
    Local $vContent, $IsEmpty
    Do
        $vContent = Execute($sArraySubscript)

        If IsArray($vContent) Then
            $IsEmpty = IsArrayEmpty($vContent) ; <-- recursive call for nested arrays
        Else
            ; check out your "voidness" logic here
            ; ------------------------------------
            $IsEmpty = (Not $vContent) ; ...... up to you decide
        EndIf

        If Not $IsEmpty Then Return False ; Is not Empty

        For $i = 0 To $iDimensions - 1
          $aLoops[$i][1] = Mod($aLoops[$i][1] + 1, $aLoops[$i][0])
          If $aLoops[$i][1] Then ExitLoop
        Next
    Until $i = $iDimensions
    Return True ; Is Empty
EndFunc   ;==>IsArrayEmpty

 

Edited by Nine
Link to comment
Share on other sites

Another one : 

Func IsArrayEmpty($aArray)
    Local $iIndex, $iCount = 1, $sArray
    Local $iDimensions = UBound($aArray, 0)
    If @error Then Return SetError(1, 0, 0)
    For $i = 1 To $iDimensions
        $iCount *= UBound($aArray, $i)
    Next
    Local $iStep = $iCount, $iLastStep = $iCount
    For $i = 1 To $iDimensions
        If $i > 1 Then $iLastStep = $iStep
        $iStep /= UBound($aArray, $i)
        $iIndex = -1
        $sArray = ""
        For $j = 0 To $iCount - 1
            $iIndex += 1
            If $iIndex = $iLastStep Then $iIndex = 0
            $sArray &= "[" & Int($iIndex/$iStep) & "]"
            If $i = $iDimensions Then
                If Execute("$aArray" & $sArray) <> "" Then Return 0
            EndIf
        Next
    Next
    Return 1
EndFunc

 

Link to comment
Share on other sites

On 5/19/2024 at 7:27 PM, Nine said:

@Gianni  Very clever code you made there.  I was not aware of it, thank you for sharing.Hi

I had a bit of a hard time understanding the behavior of $x.  So I changed it (hope you don't mind :sweating:) to make it, IMO, easier to read.

Hi @Nine

Thanks for simplifying the code.
My "reduction" was just a quick adaptation of more complicated code intended to simulate nested For-Next loops with the ability to set the initial value of each loop, different step values both positive and negative for each nesting... just like the real For -next loops. (for those interested and needing to use it, the complete code for the For-Next simulator can be found herehttps://www.autoitscript.com/forum/topic/180468-traversing-array/?do=findComment&comment=1296451 )

The adaptation used here, as well as your optimization, only allows simpler loops but which for this use case are optimal.

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

On 5/21/2024 at 10:02 AM, jguinch said:

Another one : 

Func IsArrayEmpty($aArray)
    Local $iIndex, $iCount = 1, $sArray
    Local $iDimensions = UBound($aArray, 0)
    If @error Then Return SetError(1, 0, 0)
    For $i = 1 To $iDimensions
        $iCount *= UBound($aArray, $i)
    Next
    Local $iStep = $iCount, $iLastStep = $iCount
    For $i = 1 To $iDimensions
        If $i > 1 Then $iLastStep = $iStep
        $iStep /= UBound($aArray, $i)
        $iIndex = -1
        $sArray = ""
        For $j = 0 To $iCount - 1
            $iIndex += 1
            If $iIndex = $iLastStep Then $iIndex = 0
            $sArray &= "[" & Int($iIndex/$iStep) & "]"
            If $i = $iDimensions Then
                If Execute("$aArray" & $sArray) <> "" Then Return 0
            EndIf
        Next
    Next
    Return 1
EndFunc

 

Hi @jguinch

Looks like the list needs some fixing. Also it wasn't designed to accept nested arrays, right?

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 2 weeks later...
Posted (edited)
On 5/23/2024 at 4:22 PM, jguinch said:

@Gianni : Not, it was not designed for nested arrays. Like you said,  "up to you decide" 😀

Hi @jguinch
regardless of nested arrays, what I mean is that the script you posted above doesn't seem to work as it is

if we want to implement that "paradigm", then this script seems to work. (by the way, this also works with nested arrays)
(p.s. I hope there are no bugs here... 😀)

Further interesting reading about this topic:

https://codegolf.stackexchange.com/questions/79609/index-of-a-multidimensional-array

https://codegolf.stackexchange.com/questions/37905/mixed-base-conversion

...As mentioned in a comment in the first of above links:
"Indexing a multidimensional array is essentially mixed base conversion"

p.s.

... I forgot to give credit. The mathematics behind the script is by @Nine from this topic: https://www.autoitscript.com/forum/topic/206284-mixed-base-conversion-coding-challenge/

_Example()

Func _Example()
    Local $aExampleArray[2][3][4] = [[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0]]]
    Local $aExampleArray1[2][3][4] = [[["Hello", "", "", ""], ["", "", "", ""], ["", "", "", ""]], [["", "", "", ""], ["", "", "", ""], ["", "", "", ""]]]
    $aExampleArray[1][2][3] = $aExampleArray1 ; <-- here I inject a nested array
    MsgBox(0, "Example", "Is Array empty? -> " & _ArrayIsEmpty($aExampleArray))
EndFunc   ;==>_Example


; #FUNCTION# ====================================================================================================================
; Name ..........: _ArrayIsEmpty
; Description ...: Scans an entire array to check if it is "empty"
; Syntax ........: _ArrayIsEmpty(Byref $aInput)
; Parameters ....: $aInput              - [in] an array
;
; Return values .: Success              - True or False (depending on whether empty or not empty)
;
;                                       - If passed argument is not an array
;                                         @error is set to 1 and returns the Null value
;
; Author ........: Gianni
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ArrayIsEmpty(ByRef $aInput)
    If Not IsArray($aInput) Then Return SetError(1, 0, Null)
    Local $iSubscripts = UBound($aInput, 0), $aSubscripts[$iSubscripts], $sDimensions, $iSubscriptElements
    Local $iTotElements = 1, $sLeadingZero, $vContent, $bIsEmpty, $iDigit = -1
    For $i = 0 To $iSubscripts - 1
        $aSubscripts[$i] = UBound($aInput, $i + 1)
        $iTotElements *= $aSubscripts[$i]
        $sLeadingZero &= '[0]'
    Next
    For $iIndex = 0 To $iTotElements - 1
        $iSubscriptElements = $iIndex
        $sDimensions = $iSubscriptElements ? "" : "[0]"
        While $iSubscriptElements ; Calculate the value of each subscript
            $iDigit += 1
            $multiplier = $aSubscripts[$iSubscripts - Mod($iDigit, $iSubscripts) - 1]
            $sDimensions = "[" & Mod($iSubscriptElements, $multiplier) & "]" & $sDimensions
            $iSubscriptElements = Floor($iSubscriptElements / $multiplier)
        WEnd
        $iDigit = -1
        $sDimensions = StringMid($sLeadingZero & $sDimensions, StringInStr($sLeadingZero & $sDimensions, '[', 0, -$iSubscripts))
        $vContent = Execute("$aInput" & $sDimensions)
        ; ConsoleWrite("Debug: " & $sDimensions & @TAB & $vContent & @TAB & VarGetType($vContent) & @CRLF)
        $bIsEmpty = IsArray($vContent) ? _ArrayIsEmpty($vContent) : Not $vContent
        If Not $bIsEmpty Then Return False ; Is not empty
    Next
    Return True ; Is empty
EndFunc   ;==>_ArrayIsEmpty

 

Edited by Gianni
...forgot to give credit and added some reference links

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...