Option Explicit
Public Sub ArrayStuff()
Dim arr(0 To 5) As Long, i As Long
For i = 0 To 5
arr(i) = i
Next
'Loop only required indices
For i = 2 To 3
Debug.Print arr(i)
Next
'Slice via Application.WorksheetFunction.Index
Dim arr2(0 To 2, 0 To 2) As Long, j As Long, counter As Long
For i = LBound(arr2, 1) To UBound(arr2, 1) '<== here can specify particular rows
For j = LBound(arr2, 2) To UBound(arr2, 2) '<== here can specify particular columns
counter = counter + 1
arr2(i, j) = counter
Next
Next
MsgBox Join(Application.WorksheetFunction.Transpose(Application.WorksheetFunction.Index(arr2, 0, 1)), ",") 'slice a column out
MsgBox Join(Application.WorksheetFunction.Index(arr2, 1, 0), ",") 'slice a row out
MsgBox Join(Application.WorksheetFunction.Index(arr2, 2, 0), ",") 'slice a row out
End Sub
' The Slice function takes an input array and returns a new array
' that contains a subset of the elements from the input array.
'
' The subset is defined by the `startIndex`, `stopIndex`, and `stepCount`
' parameters.
'
' The `startIndex` parameter specifies the index of the first
' element to include in the result. If `startIndex` is negative,
' it counts from the end of the input array.
'
' The `stopIndex` parameter specifies the index of the first element
' to exclude from the result. If `stopIndex` is negative, it counts
' from the end of the input array.
'
' The `stepCount` parameter specifies how many elements to skip
' between each element in the result. For example, if `stepCount`
' is 2, every other element will be included in the result. If
' `stepCount` is negative then it works in reverse order.
'
' @author Robert Todar <robert@roberttodar.com>
Public Function Slice( _
ByVal arr As Variant, _
Optional ByVal startIndex As Long = 0, _
Optional ByVal stopIndex As Long = 0, _
Optional ByVal stepCount As Long = 1 _
) As Variant
Dim result As Variant
Dim currentIndex As Long
Dim resultIndex As Long
If stepCount = 0 Then
Err.Raise 5, "Slice", "Step count must be greater than or less than zero."
Exit Function
End If
' Handle negative indices for startIndex and stopIndex by
' converting them to positive indices.
If startIndex < 0 Then startIndex = UBound(arr) + 1 + startIndex
If stopIndex < 0 Then stopIndex = UBound(arr) + 1 + stopIndex
If stepCount > 0 Then
' Calculate the stop index if it is not provided (i.e., if it is zero).
If stopIndex = 0 Then stopIndex = UBound(arr) + 1
' Calculate the size of the result array based on
' start/stop indices and step count.
resultIndex = (stopIndex - startIndex) \ stepCount - 1
' Adjust the stopIndex as it is excluded from the results.
' This is done after getting the resultIndex as the array
' is base 0 and will still need to account for that 0 index.
stopIndex = stopIndex - 1
Else
' If no input is provided then the start and
' stops need to get flipped from the start to
' the end.
If startIndex = 0 Then startIndex = UBound(arr)
If stopIndex = 0 Then stopIndex = -1
' Need to add 1 to the stopindex as it needs to
' be excluded from the results. In this senerio,
' this is done before the resultIndex is calculated as
' we don't have to account for the 0 index.
stopIndex = stopIndex + 1
resultIndex = (startIndex - stopIndex) \ Abs(stepCount)
End If
' Create a new array with appropriate size to store results.
' and get the starting result index. This will be incremented
' each iteration.
ReDim result(0 To resultIndex)
resultIndex = LBound(result)
' Fill in values for resulting array using start/stop indices
' and step count as specified by user inputs.
For currentIndex = startIndex To stopIndex Step stepCount
result(resultIndex) = arr(currentIndex)
resultIndex = resultIndex + 1
Next currentIndex
' Return resulting sliced array back to user.
Slice = result
End Function
3条答案
按热度按时间sdnqo3pr1#
在VBA中,与Python不同,我们不能直接“子集”数组。
我们只能通过指定
i
和j
在某些边界之间来循环索引,例如i
在第1行和第2行之间,j
在第2列和第3列之间。当然,我们也可以直接通过位置索引数组,例如arr(1)
。i
只是一个表示行索引的变量,j
列索引。或者,我们可以使用
Index
来“切片”出特定的行或列;我猜你可能会称之为子集,但从你的语法来看,我认为你是在以Python的方式思考。Application.WorksheetFunction.Index(array,n, 0)
将从阵列中分割行n
Application.WorksheetFunction.Index(array, 0, n)
将列n
从数组中切片出来k0pti3hp2#
对于任何不想使用循环或范围方法来处理这个问题的人,这里有一个经过测试的解决方案来处理数组的子集(不需要是整行或整列):
它将数组的第2个到第5个元素(1,2,3,4,5)求和。对于二维数组,只需执行以下操作:
将计算二维数组“DataArray”的五个元素子集(行17到21,列5)的平均值。
顺便说一句,我还没有尝试评估这种方法的效率,但它确实是一种变通方法。希望这能有所帮助。
cxfofazt3#
Python切片克隆
我最近想要的功能与您在示例中给出的功能相同,它基本上模仿了Python的slice方法-所以我决定编写代码来实现这一点。
请随意阅读我的代码注解,以了解它是如何工作的,但它应该与python的
[start:stop:step]
相同。需要注意的是,我写这段代码时确实期望将base设置为0,所以如果你的base不同,代码可能需要首先增强。
演示
下面是一个演示,展示了Python方法与我的版本的比较。
测试
此外,我还提供了这个方法的测试脚本。