Arrays 返回数组时类型不匹配
我正在编写一个VBScript函数,它接受字符串数组,并返回按字母顺序排序的相同字符串数组。理想情况下,我希望此函数的工作方式与uCase函数完全相同(作为示例),您可以说:Arrays 返回数组时类型不匹配,arrays,sorting,types,vbscript,mismatch,Arrays,Sorting,Types,Vbscript,Mismatch,我正在编写一个VBScript函数,它接受字符串数组,并返回按字母顺序排序的相同字符串数组。理想情况下,我希望此函数的工作方式与uCase函数完全相同(作为示例),您可以说: myString = ucase(mystring) 其中,“myString”的值将替换为其内容的大写版本 但是,当我在测试脚本中设置一个数组,然后将它提供给排序函数时,我会得到一个类型不匹配错误,将结果分配给原始变量。我所能理解的是VBScript不能允许您用另一个数组覆盖一个数组,因为TypeName函数告诉我,我
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无法执行我希望它在这里执行的操作?简短回答:您的
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
要了解如何处理固定/动态阵列,请使用wrt复制与就地修改。固定数组-不能被“覆盖”-应就地排序/保留内存;可以将所有阵列复制到动态阵列中
受虐狂可能会看到一个简单的解决办法:使用一个物体
@你猜错了;testArray从一个破碎的固定变体数组开始。我来试一试。谢谢我喜欢认为我相当擅长使用VBScript解决问题,然后我遇到这样的答案,并认为“哇…我的解决方案有点粗糙…”感谢有用的讨论。在填充长度未知的列表时,我总是使用动态数组(例如,从文本文件加载字符串列表),这就是我在示例脚本中以这种方式创建testArray变量的原因。我没有遇到下面由Ansgar Wiechers描述的“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