Asp classic VB:如何获取数组元素的索引(如果用于每个

Asp classic VB:如何获取数组元素的索引(如果用于每个,asp-classic,vbscript,Asp Classic,Vbscript,我在.asp文件中编写了以下VB脚本 Dim myArr(5, 6) '// a 6 * 7 array For i = LBound(myArr, 1) to UBound(myArr, 1) For j = LBound(myArr, 1) to UBound(myArr, 1) myArr(i, j) = "i:" & i & ", j:" & j next next Dim i i = 0 For Each k In myAr

我在.asp文件中编写了以下VB脚本

Dim myArr(5, 6) '// a 6 * 7 array

For i = LBound(myArr, 1) to UBound(myArr, 1)
    For j = LBound(myArr, 1) to UBound(myArr, 1)
        myArr(i, j) = "i:" & i & ", j:" & j
    next
next

Dim i
i = 0

For Each k In myArr
    Response.Write("i:" & i ", k:" & k & "<br>")
    i = i + 1
Next
Dim myArr(5,6)//6*7数组
对于i=LBound(myArr,1)到UBound(myArr,1)
对于j=LBound(myArr,1)到UBound(myArr,1)
myArr(i,j)=“i:&i&”,j:&j
下一个
下一个
昏暗的我
i=0
对于myArr中的每个k
回答。写下(“i:&i”,k:&k&“
”) i=i+1 下一个
使用For Each可以遍历所有数组项, 问题是如何得到每个维度的索引


例如:如何在第10个循环(即2和4)之后获得k索引?

您不能。For each被定义为在返回下一个对象时迭代对象,而不必知道对象的数量(如接口中所定义的)(使多线程成为可能)

也没有指定接收对象的顺序与放置对象的顺序完全相同(尽管我从未体验过数组的其他顺序),这取决于为集合指定的枚举器接口对象

幸运的是,还有其他一些技巧可以满足您的需要,但具体实现取决于您试图解决的问题。
例如,可以将数组与数组一起使用,也可以使用System.Collections.ArrayList中的ArrayList类,或者创建自己的类来存储值或对象


请注意:关于这个答案的正确性有一些讨论,请参见下面的评论。我将学习这个主题,并分享我从中获得的任何相关经验。

使用嵌套For循环,而不是每个循环

for i = 0 to ubound(myArr)
     for y = 0 to ubound(myArr, 2)
        ' do something here...
    next
next

可以创建如下所示的辅助对象:

Option Explicit
dim myArr(5,6) 
dim i, j, k

For i = LBound(myArr, 1) to UBound(myArr, 1)
    For j = LBound(myArr, 2) to UBound(myArr, 2)    
        Set myArr(i, j) = [new LookupObject]("i:" & i & ", j:" & j, i, j)
    next
next

For Each k In myArr
    Response.Write("This is k:" & k & "<br>")
    Response.Write("i index of k: " & k.I & "<br>")
    Response.Write("j index of k: " & k.J & "<br>")
Next

Public Function [new LookupObject](value, i, j)
    Set [new LookupObject] = (new cls_LookupObject).Init(value, i, j)
End Function

Class cls_LookupObject

    Private value_, i_, j_

    Public Function Init(value, i, j)
        i_ = i
        j_ = j
        value_ = value
        Set Init = me
    End Function

    Public Default Property Get Value()
        Value = value_
    End Property

    Public Property Get I()
        I = i_
    End Property

    Public Property Get J()
        J = j_
    End Property

End Class
选项显式
dim myArr(5,6)
暗i,j,k
对于i=LBound(myArr,1)到UBound(myArr,1)
对于j=LBound(myArr,2)到UBound(myArr,2)
设置myArr(i,j)=[newlookupobject](“i:&i&”,j:&j,i,j)
下一个
下一个
对于myArr中的每个k
回答。写下(“这是k:&k&“
”) 回答。写下(“k的i索引:&k.i&“
”) 回答。写下(“k的j索引:&k.j&“
”) 下一个 公共函数[new LookupObject](值,i,j) 设置[new LookupObject]=(新cls_LookupObject).Init(值,i,j) 端函数 类cls_LookupObject 私人价值,i,j_ 公共函数Init(值,i,j) 我=我 j_uj=j 值 Set Init=me 端函数 公共默认属性获取值() 价值=价值_ 端属性 公共财产 I=I_ 端属性 公共财产 J=J_ 端属性 末级
免责声明:由于我在非Windows机器上创建了此代码,因此无法对其进行测试。您可能会发现一些语法或设计错误。命名不是很好,但这样更符合您的概念

尽管如此,您似乎正在寻找一个简单的解决方案。不会带来更多的“挑战”:当您想在数组中传递保留其内部索引的值时,您需要设置它们,而不仅仅是分配它们:这会降低可移植性。

当您使用对象时,您需要知道对象引用与原语相比是如何工作的,否则您会在不期望的情况下得到一些意外的值更改行为

更新

如果有人对VBScript与其他语言在以下方面的比较感兴趣 到数组,foreach循环,尤其是获取有关 “For Each”交付的元素在循环集合中的位置, 会提出这样的问题:

VBScript在数组方面与其他语言相比如何, foreach循环,尤其是获取有关 由“For Each”交付的元素在集合中的位置 循环

那么,很早以前就有了一个简短的答案:

foreach循环构造可以提供

  • 指针(内存地址)-例如C/C++所做的;那你必须 取消引用指针以获取您甚至可以访问的元素 改变位置信息(可通过指针算法获得)
  • 引用(别名)(如Perl所做的;允许修改, 但显然没有位置的计算(除非元素 意外包含此类信息)
  • 副本(如Python或VBScript;既不修改也不修改) 检索元信息是可能的(除非某种类型和聪明的 像AutomatedChaos或AnthonyWJones这样的灵魂竭尽全力 通过向提交循环变量来实现类似C/C++的解决方案 div和MODs分别设计一个类,该类允许扩展 普通/基本数据值(含元信息)
  • 您可以放心地忽略我其余的答案;我只是不想删除 以下文本为讨论提供了一些背景。

    这个问题不能解决,除非

    (1) armen用现实世界的术语描述了现实世界问题的背景-数组来自哪里,可能有多少个维度,是什么决定了维度 结构(行/列/…),在For Each循环中必须执行哪些操作,为什么索引对这些操作很重要

    (2) 所有贡献者都获得了正确的维度选择器:

    For i = LBound(myArr, 1) to UBound(myArr, 1)
        For j = LBound(myArr, 1) to UBound(myArr, 1)
    
    如果不将一行中的1替换为2,则不清楚代码的行/列结构是什么

    为了证明我愿意以一种更具建设性的方式做出贡献,我加入了一个函数来获取任意数组的(维数):

    Function getDimensions(aVBS)
      Dim d : d = 0
      If IsArray(aVBS) Then
         For d = 1 To 60
          On Error Resume Next
           UBound aVBS, d + 1
           If Err.Number Then Exit For
          On Error GoTo 0
         Next
      End If
      getDimensions = d
    End Function ' getDimensions
    
    (基于和)

    更新:仍然不是解决方案,但值得思考

    由于armen(到目前为止)没有提供他问题的真实情况,我试图 给你一个反复无常的(给行和列加上上下文等等) 你可以称之为第三维的东西):

    让我们来看看萨
    # Results of the F# tests
    # 2 (fixed) students, 3 (fixed) test,
    # 4>5 (dynamic) criteria for each test
    
    Students  Ann       Bill
        Test  TA TB TC  TA TB TC
    Criteria
      CA       1  2  3   4  5  6
      CB       7  8  9  10 11 12
      CC      13 14 15  16 17 18
      CD      19 20 21  22 23 24
    # CE      25 26 27  28 29 30
    
    Function getXlsRange(sSheet, sRange)
      Dim oX : Set oX = CreateObject("Excel.Application")
      Dim oW : Set oW = oX.Workbooks.Open(resolvePath("..\data\hogmond.xls"))
      getXlsRange = oW.Sheets(sSheet).Range(sRange).Value
      oW.Close
      oX.Quit
    End Function ' getXlsRange
    
    Function getAdoRows(sSQL)
      Dim oX : Set oX = CreateObject("ADODB.Connection")
      oX.open Join(Array(     _
            "Provider=Microsoft.Jet.OLEDB.4.0" _
          , "Data Source=" & resolvePath("..\data\hogmond.xls") _
          , "Extended Properties="""           _
              & Join(Array(     _
                    "Excel 8.0" _
                  , "HDR=No"    _
                  , "IMEX=1"    _
                ), ";" )        _
              & """"            _
      ), ";")
      getAdoRows = oX.Execute(sSQL).GetRows()
      oX.Close
    End Function ' getAdoRows
    
    Sub showAFE(sTitle, aX)
      Dim i, e
      WScript.Echo "For Each:", sTitle
      WScript.Echo "type:", VarType(aX), TypeName(aX)
      WScript.Echo "dims:", getDimensions(aX)
      WScript.Echo "lb  :", LBound(aX, 1), LBound(aX, 2)
      WScript.Echo "ub  :", UBound(aX, 1), UBound(aX, 2)
      WScript.Echo "s   :", UBound(aX, 1) - LBound(aX, 1) + 1 _
                          , UBound(aX, 2) - LBound(aX, 2) + 1
      i = 0
      For Each e In aX
          WScript.Echo i & ":", e
          i = i + 1
      Next
    End Sub ' showAFE
    
      showAFE "VTA according to XlsRange:", getXlsRange("VTA", "B3:D4")
      showAFE "VTA according to AdoRows:",  getAdoRows("SELECT * FROM [VTA$B3:D4]")
    
    For Each: VTA according to XlsRange:
    type: 8204 Variant()
    dims: 2
    lb  : 1 1
    ub  : 2 3
    s   : 2 3
    0: 1
    1: 2
    2: 3
    3: 4
    4: 5
    5: 6
    For Each: VTA according to AdoRows:
    type: 8204 Variant()
    dims: 2
    lb  : 0 0
    ub  : 2 1
    s   : 3 2
    0: 1
    1: 3
    2: 5
    3: 2
    4: 4
    5: 6
    
      Dim a : a = Array(1, 2, 3)
      Dim e
      WScript.Stdout.WriteLine "no problem looping over (" & Join(a, ", ") & ")"
      For Each e In a
          WScript.Stdout.Write " " & e
      Next
      ReDim Preserve a(UBound(a) + 1)
      a(UBound(a)) = 4
      WScript.Stdout.WriteLine
      WScript.Stdout.WriteLine "no problem growing the (dynamic) array (" & Join(a, ", ") & ")"
      WScript.Stdout.WriteLine "trying to grow in loop"
      For Each e In a
          WScript.Stdout.Write " " & e
          If e = 3 Then
            On Error Resume Next
             ReDim Preserve a(UBound(a) + 1)
             If Err.Number Then WScript.Stdout.Write " " & Err.Description
            On Error GoTo 0
             a(UBound(a)) = 5
          End If
      Next
      WScript.Stdout.WriteLine
    
    no problem looping over (1, 2, 3)
     1 2 3
    no problem growing the (dynamic) array (1, 2, 3, 4)
    trying to grow in loop
     1 2 3 This array is fixed or temporarily locked 5
    
    for i = 0 to ubound(myArr)
             for y = 0 to ubound(myArr, 1)
    
        [UBound(a) and UBound(a, 1) are synonyms, so this will create havoc as soon
        as the UBounds of the different dimensions are not (accidentially) the same]
    
      Dim nDim
      For Each nDim In Array(3, 59, 60, 62, 64, 65, 70)
          ReDim aDim(nDim)
          Dim sDim : sDim = "ReDim a" & nDim & "(" & Mid(Join(aDim, ",0"), 2) & ")"
          WScript.Echo sDim
         On Error Resume Next
          Execute sDim
          If Err.Number Then WScript.Echo Err.Description
         On Error GoTo 0
      Next
    
    ReDim a3(0,0,0)
    ...
    ReDim a64(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0)
    ReDim a65(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
    Subscript out of range
    ...
    
    Option Explicit
    Dim aaa(1,1,1)
    
    Dim s : s = ""
    
    Dim i, j, k
    For i = LBound(aaa, 3) To UBound(aaa, 3)
        For j = LBound(aaa, 2) To UBound(aaa, 2)
            For k = LBound(aaa, 1) To UBound(aaa, 1)
                aaa(k, j, i) =  4 * i + 2 * j + k
            Next
        Next
    Next
    
    Dim x
    For Each x in aaa
        s = s + CStr(x) + " : "
    Next
    
    MsgBox s    
    
    Function GetNumberOfDimensions(arr)
        On Error Resume Next
    
        Dim i
    
        For i = 1 To 60000
            LBound arr, i
            If Err.Number <> 0 Then
                GetNumberOfDimensions = i - 1
                Exit For
            End If
        Next
    
    End Function
    
    Dim arr(3,3,3)
    
    Dim s : s = ""
    
    Dim i, j, k
    For i = LBound(arr, 3) To UBound(arr, 3)
        For j = LBound(arr, 2) To UBound(arr, 2)
            For k = LBound(arr, 1) To UBound(arr, 1)
                arr(k, j, i) =  16 * i + 4 * j + k
            Next
        Next
    Next
    
    Dim dimCount : dimCount = GetNumberOfDimensions(arr)
    Redim dimSizes(dimCount - 1)
    
    For i = 1 To dimCount
        dimSizes(i - 1) = UBound(arr, i) - LBound(arr, i) + 1
    Next
    
    Dim index : index = 0
    Dim item
    For Each item in arr
    
        s = "(" 
        Dim indexValue, dimIndex
        indexValue = index
        For dimIndex = 0 To dimCount - 1
            s = s + CStr((indexValue mod dimSizes(dimIndex)) - LBound(arr, dimIndex + 1)) + ", "
            indexValue = indexValue \ dimSizes(dimIndex)
        Next
        Response.Write Left(s, Len(s) - 2) + ") = " + Cstr(item) + "<br />"
        index = index + 1
    Next