【问题标题】:Zero-length arrays in VBScriptVBScript 中的零长度数组
【发布时间】:2010-01-21 09:17:03
【问题描述】:

我必须做一些 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

【问题讨论】:

标签: arrays vbscript


【解决方案1】:

为:

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 运行时错误:下标超出范围:'UBound'”。

一个测试数组是“暗淡”还是“空”的通用函数也应该(可能)测试变量是否实际上是一个数组。

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% 的时间在检查数组是否为“Dimensioned”时,是否需要获取数组的 UBound 并且在数组为没有尺寸。所以我通常会将 UBound 作为参数传递,例如:

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

我不知道这种做法是否真的节省了任何“时间”,但它确实在几乎每次使用时都节省了 1 行代码,并且是一种执行错误检查实践的简单方法。

另外,为了完整性,我将其包括在内,但实际上,在 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 将被跳过。

【讨论】:

    【解决方案2】:

    使用Array 函数创建或由其他内部VBScript 函数(例如Split)返回的空数组的上限为-1。所以你可以像这样测试一个空数组:

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

    更多信息在这里:Testing for Empty Arrays

    【讨论】:

    • 您的代码不正确,因为 UBound 在空数组上失败。您链接的页面证实了我的怀疑,即唯一的方法是检测抛出异常(或通过我的“for each”hack)。这很可悲:-/
    • @angus:他是正确的,因为他的代码看起来像“dim results : results = Array()”
    • Helen 的答案在第一行有关键——“使用 Array 函数......”。答案中缺少的是对您做错了什么的解释。这就是@Totonga 所指出的:如果你像这样声明你的数组“Dim someArray()”,它们 UBound 将返回未定义。如果你这样声明它“Dim someArray : Array()”,那么 UBound 将返回 -1。
    • 哎呀。声明应该是“Dim someArray : someArray = Array()”
    【解决方案3】:

    如果您的方法应该能够返回一个空数组,您的代码必须是这样的

    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 each 循环中没有循环。

    【讨论】:

      【解决方案4】:

      我认为这是在 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
      

      【讨论】:

        【解决方案5】:

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

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

        它对我有用。

        【讨论】:

          猜你喜欢
          • 2012-09-06
          • 2010-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-10
          • 2017-02-26
          相关资源
          最近更新 更多