4

我正在编写一个 VBScript 函数,它接受一个字符串数组并返回一个按字母顺序排序的相同字符串的数组。理想情况下,我希望这个函数的工作方式与(例如)uCase 函数完全一样,您可以在其中说:

myString = ucase(mystring)

“myString”的值将被其内容的大写版本替换。

但是当我在我的测试脚本中设置一个数组,然后将它提供给我的排序函数时,我得到一个类型不匹配错误,将结果分配给原始变量。我所能想到的是,VBScript 不能让你用另一个数组覆盖一个数组,因为 TypeName 函数告诉我我正在使用的输入变量和排序函数的输出都是相同的类型(“Variant() ”)。

这是我的示例代码,可以为您提供更具体的工作:

Option Explicit
Dim testArray(), thisItem, sortedArray 
ReDim testArray(9)

testArray(0)="Xylophone"
testArray(1)="Elephant"
testArray(2)="Ferret"
testArray(3)="Eel"
testArray(4)="Dinosaur"
testArray(5)="Barracuda"
testArray(6)="Ape"
testArray(7)="Weasel"
testArray(8)="Firebird"
testArray(9)="Phoenix"

WScript.Echo "Starting Array:"
For Each thisItem In testArray
  WScript.Echo "  " & thisItem
Next

' This line will work fine, assigning Variant() to Empty sortedArray
sortedArray = SortArray(testArray)
' This line will generate a type mismatch, assigning Variant() to Variant()
testArray = SortArray(testArray)

WScript.Echo "Sorted Array:"
For Each thisItem In sortedArray
   WScript.Echo "  " & thisItem
Next

WScript.Quit 0

Function SortArray(ByVal inArray)

   Dim a, b, swapVal 

   For a = UBound(inArray) - 1 To 0 Step -1
      For b = 0 To a
         If inArray(b) > inArray(b+1) Then
            swapVal = inArray(b+1)
            inArray(b+1) = inArray(b)
            inArray(b) = swapVal
         End If
      Next
   Next

   SortArray = inArray

End Function 

如果您按原样运行此示例代码,您会发现以“sortedArray=”开头的行可以正常工作。下面以 "testArray=" 开头的行将生成类型不匹配错误。

理想情况下,我希望此功能能够运行,以便这些行中的任何一个或两个都可以正常工作。(换句话说,当我以后使用它时,我不想想“哦,是的,我必须创建另一个变量并将输出分配给它而不是我的原始变量。”)

我是否遗漏了什么,或者 VBScript 无法做我希望它在这里做的事情?

4

2 回答 2

4

简单的解决方案:使用一个System.Collections.ArrayList对象。

Set testArray = CreateObject("System.Collections.ArrayList")
testArray.Add "Xylophone"
testArray.Add "Elephant"
...
testArray.Add "Phoenix"

testArray.Sort

For Each thisItem In testArray
  WScript.Echo "  " & thisItem
Next
于 2013-06-06T22:01:59.270 回答
4

简短的回答:你Dim testArray()创建了一个可憎的 - 一个固定的数组,没有大小,VBScript 无法正确处理(只需尝试使用它的 UBound())。如果您删除那些 (),您的脚本将起作用。

一个长答案的开始:看看这个示例代码:

Option Explicit

Dim aDyn : aDyn = Split("Xylophone Elephant Ferret Ape Weasel")
WScript.Echo 0, "   aDyn:", Join(aDyn)
Dim aDynCpy : aDynCpy = getSortedArray(aDyn)
WScript.Echo 1, "aDynCpy:", Join(aDynCpy)
WScript.Echo 2, "   aDyn:", Join(aDyn)

Dim aFix(4) ' we want an optimized/non-growable fixed array
Dim i
For i = 0 To UBound(aFix)
    aFix(i) = aDyn(i)
Next
WScript.Echo 3, "   aFix:", Join(aFix)
SortArray aFix ' sort in place/reserved memory
WScript.Echo 4, "   aFix:", Join(aFix)

aDynCpy = aDyn ' DYN: no problem
WScript.Echo 5, "aDynCpy:", Join(aDynCpy)
aDynCpy = getSortedArray(aFix) ' DYN: no problem
WScript.Echo 6, "aDynCpy:", Join(aDynCpy)

On Error Resume Next
aFix = aDyn ' FIX: not possible
WScript.Echo 7, Err.Description
On Error GoTo 0

WScript.Quit 0

Function getSortedArray(ByVal inArray) ' let VBScript do the copy
  SortArray inArray ' sort copy in place
  getSortedArray = inArray
End Function

Sub SortArray(inArray) ' ByRef/Default, because we sort in place
   Dim a, b, swapVal
   For a = UBound(inArray) - 1 To 0 Step -1
      For b = 0 To a
         If inArray(b) > inArray(b+1) Then
            swapVal = inArray(b+1)
            inArray(b+1) = inArray(b)
            inArray(b) = swapVal
         End If
      Next
   Next
End Sub

输出:

cscript X6971815.vbs
0    aDyn: Xylophone Elephant Ferret Ape Weasel
1 aDynCpy: Ape Elephant Ferret Weasel Xylophone
2    aDyn: Xylophone Elephant Ferret Ape Weasel
3    aFix: Xylophone Elephant Ferret Ape Weasel
4    aFix: Ape Elephant Ferret Weasel Xylophone
5 aDynCpy: Xylophone Elephant Ferret Ape Weasel
6 aDynCpy: Ape Elephant Ferret Weasel Xylophone
7 Type mismatch

了解如何处理固定/动态数组以复制与就地修改。固定数组——不能被“覆盖”——应该就地排序/它们的保留内存;所有数组都可以复制到动态数组中。

受虐狂可能会看这个恶心的讨论

于 2013-06-06T21:17:10.893 回答