将一维数组乘以一维数组或常数 - VBA

Multiply 1D-array by 1D-array or Constant - VBA

冒着成为话题的风险,我决定分享一些代码,Q&A-style。如果普遍认为这与主题无关,我很乐意在需要时将其删除。

背景:

我一直想知道是否有可能 return 一个一维数组通过将另一个一维数组乘以一个常数值或第三个一维数组(相同大小)没有迭代。

所以我正在寻找的过程如下所示:


示例代码:

我已经看到有关此主题的问题,但我还没有看到无需迭代即可完成此操作的答案。我见过的最接近的是来自@SiddharthRout,在 external 论坛上。

但通常人们会选择迭代:

Sub Test()
    
    Dim arr1 As Variant: arr1 = Array(1,2,3)
    Dim y As Long, x As Long: x = 3 'Our constant
    
    For y = LBound(arr1) To UBound(arr1)
        arr1(y) = arr1(y) * x
    Next y
    
    End Sub

Sub Test()

Dim arr1 As Variant: arr1 = Array(1, 2, 3)
Dim arr2 As Variant: arr2 = Array(3, 4, 5)
Dim y As Long

For y = LBound(arr1) To UBound(arr1)
    arr1(y) = arr1(y) * arr2(y)
Next y

End Sub


问题:

如何通过将另一个一维数组乘以任何常数或另一个(大小相等的)一维数组而不进行迭代来检索一维数组?

根据我的发现,答案的关键在于 MMULT、return 乘以行*列的数组。


一维数组乘以常数

Sub Multiply_1D_byConstant()

Dim arr1 As Variant: arr1 = Array(1, 4, 3, 5, 10, 15, 13, 11, 6, 9)

With Application

    Dim x As Long: x = 3 'Our constant
    Dim y As Long: y = UBound(arr1) + 1

    Dim arr2 As Variant: arr2 = .Evaluate("TRANSPOSE(ROW(" & x + 1 & ":" & x + y + 1 & ")-ROW(1:" & y + 1 & "))")
    Dim arr3 As Variant: arr3 = .Evaluate("TRANSPOSE(ROW(1:" & y & "))")
    Dim arr4 As Variant: arr4 = .Index(.MMult(.Transpose(arr1), arr2), arr3, 1)

End With

End Sub

在这里,.Evaluate 将很快 return 一维数组 n 乘以我们的常量,n 为 Ubound(arr1)+1。在上面的例子中:{3,3,3,3,3,3,3,3,3,3}

我们比 .Transpose arr1 在我们的 .MMult(.Transpose(arr1), arr2) 中将 return 一个二维数组。因为我们需要对其进行迭代,所以我们宁愿切入数组以通过 .Index 提取一维数组。上面的结果是:

{3, 12, 9, 15, 30, 45, 39, 33, 18, 27}

可视化其工作原理:.MMult 将 return 上面示例中的二维数组,如下所示:

然后,因为我们基本上给 .Index 一个类似于 {1,2,3,4,5,6,7,8,9,10} 的数组,但是以动态方式,对于行和第一列只有 1,.Index 将切片 a此二维数组中的一维数组:


将一维数组乘以一维数组

这会起到同样的作用。让我们想象一下:

Sub Multiply_1D_by1D()

Dim arr1 As Variant: arr1 = Array(1, 4, 3, 5, 10, 15, 13, 11, 6, 9)
Dim arr2 As Variant: arr2 = Array(2, 1, 4, 1, 2, 3, 2, 5, 2, 1)

With Application

    Dim y As Long: y = UBound(arr1) + 1
    Dim arr3 As Variant: arr3 = .Evaluate("TRANSPOSE(ROW(1:" & y & "))")
    Dim arr4 As Variant: arr4 = .Index(.MMult(.Transpose(arr1), arr2), arr3, arr3)

End With

End Sub

这次我们不告诉 .Index.MMult 的结果中提取相同的、常量的第一列,但我们给它提供与行相同的值数组。这些值需要是一维数组,因此我们动态地使用 .Evaluate 到 return 数组。所以上面的 return 是一个一维数组,例如:

{2, 4, 12, 5, 20, 45, 26, 55, 12, 9}

可视化其工作原理:.MMult 将 return 上面示例中的二维数组,如下所示:

然后,因为我们基本上给 .Index 两个数组,如 {1,2,3,4,5,6,7,8,9,10},但是以动态方式,.Index 将从这个二维数组中切出一个一维数组:


以同样的方式,您可以使用 .Index 从二维数组中切出任何一维数组,只要您使用有效的一维数组指定行和列参数即可。我希望这对任何人都有帮助。