VBScript中的零长度数组

14

我需要做一些ASP的工作,但是发现这种语言没有提供检测长度为零的数组的方法(嗯,我想你可以检测当你尝试使用它们时抛出的异常...)。如果没有任何明智的处理方式,为什么Split()会返回一个空数组呢?或者是我漏掉了什么吗?

我想出了以下hack来检测空数组,但肯定有更简单的方式。那是什么?TIA

function ArrayEmpty (a)
    dim i, res
    res = true
    for each i in a
        res = false
        exit for
    next
    ArrayEmpty = res
end function

1
也许在传递给Split()之前,你应该检查一下输入。 - Tester101
VBScript和VBA非常相似,因此请参见https://dev59.com/1nVC5IYBdhLWcg3wtzgQ#206526。 - Fionnuala
5个回答

8

对于:

Dim arr1 : arr1 = Array()
Dim arr2
Dim arr3 : ReDim arr3(1) : Erase arr3
WScript.Echo UBound(arr1)
WScript.Echo UBound(arr2)
WScript.Echo UBound(arr3)

对于arr1返回-1,但对于arr2和arr3则报错:"VBScript runtime error: Subscript out of range: 'UBound'"。

一个通用的测试数组是否“Dimmed”或“Empty”的函数也应该(可能)测试变量是否实际上是一个数组。

Function IsDimmedArray(arrParam)

Dim lintUBound : lintUBound = 0
Dim llngError  : llngError = 0

    IsDimmedArray = False
    If Not IsArray(arrParam) Then : Exit Function

 '' Test the bounds
    On Error Resume Next

        lintUBound = UBound(arrParam)
        llngError = Err.Number
        If (llngError <> 0) Then : Err.Clear

    On Error Goto 0
    If (llngError = 0) And (lintUBound >= 0) Then : IsDimmedArray = True

End Function                  ' IsDimmedArray(arrParam)

对我来说,99%的情况下,当我检查一个数组是否“已定义”时,是因为我需要获取该数组的 UBound,并且我想在数组未定义的情况下防止运行时错误。所以通常我会将 UBound 作为参数传递,例如:

Function IsDimmedArray(arrParam, intUBoundParam)
    intUBoundParam = 0
    ...

我不知道这种做法是否真正节省了任何“时间”,但它几乎在每次使用时都可以节省一行代码,并且是强制执行错误检查实践的简单方法。
此外,我为了完整性而包含它,但在实践中,在IsDimmedArray中检查"UBound >= 0"并不常用。
    If (llngError = 0) And (lintUBound >= 0) Then : IsDimmedArray = True

通常情况下不需要,因为它通常用于以下情况:

Dim arrX
Dim lintUBound
Dim intNdx

arrX = Array()
lintUBound = UBound(arrX)
WScript.Echo "arrX is an array with UBound=" & lintUBound

For intNdx = 0 to lintUBound
    WScript.Echo "This will not print: " & intNdx
Next

因此,在这种情况下,lintUBound = -1,For ... Next将被跳过。

6

使用 Array 函数创建的空数组或由其他 VBScript 内置函数(如 Split)返回的空数组,其上限为 -1。因此,您可以按照以下方式测试是否为空数组:

Dim arr : arr = Array()

If UBound(arr) >= 0 Then
  ' arr is non-empty
Else
  ' arr is empty
End If

更多信息请查看这里:测试空数组


5
你的代码有问题,因为空数组会导致 UBound 函数失败。你分享的页面证实了我的猜想:唯一的解决办法是检测是否抛出异常(或者使用我的“for each”技巧)。这真是令人沮丧 :-/ - angus
2
@angus:他是正确的,因为他的代码看起来像“dim results: results = Array()”。 - Totonga
2
Helen的回答在第一行中提到了关键点——“使用Array函数……”。但是这个回答缺少的是对你所做错误的解释。正如@Totonga所指出的那样:如果你像这样声明数组“Dim someArray()”,那么UBound将返回未定义。如果你像这样声明它“Dim someArray: Array()”,那么UBound将返回-1。 - Ickster
1
糟糕,声明应该是“Dim someArray:someArray = Array()”。 - Ickster

2
如果你的方法需要返回一个空数组,那么你的代码应该像这样:
Option Explicit

dim result : result = mymethod
if(NOT ubound(result) > 0) then MsgBox "Array Is Empty"
dim elem : for each elem in result
  MsgBox "Element"
Next

Function mymethod
  dim results : results = Array()
  mymethod = results
End Function

Array() 创建了一个 Ubound = -1 的数组,该数组在 for 循环中没有循环。


1
我认为这是一种检查VBS数组的好方法。
Dim myArray
myArray = Array()
sTest = IsArrayEmpty(myArray)
Msgbox (sTest) ' True
Function IsArrayEmpty(myArray)
    iRet = True

    If IsArray(myArray) Then
        i = 0
        For Each e In myArray
            If Not IsEmpty(e) And Len(e)>0 Then
                i = i +1
            End If
        Next
        If i>0 Then
            iRet = False
        End If
    End If
    wIsArrayEmpty = iRet
End Function

-1

我在TechNet上找到了一个帖子,建议使用VarType来检查数组:

Function ArrayEmpty (a)
    If VarType(a) < 8192 Then ArrayEmpty=True Else ArrayEmpty=False
End Function

这对我有用。


VarType总是返回8204,似乎不起作用。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接