"ekkehard.horner" <ekkehard.horner@xxxxxx> wrote in message
news:49d244ea$0$30227$9b4e6d93@xxxxxx-online.net...
turtle schrieb:
> Hello,
>
> I would like to create a function within a VBScript where I will enter
> a string (i.e person's first name) and that person's first name is
> inputted into an array so that each separate character in the array is
> a letter of the name inputted.
>
> For example:
>
> Input -- Larry
> Array -- [L,a,r,r,y]
>
> I am assumming the Split() function would be the way to go with this,
> but I am not 100% sure on the delimiter syntax.
>
> Can anyone help me? To create an array of characters from a string in a language without a
specialized
function for this task like VBScript implies that you have to access the
characters
in a loop. As evidence: Hz's hack to make the use of Split() possible
requires
such a loop to insert delimiters that then have to be transformed to
separators
to fit the logic of Split() - an extraordinary waste of space and time.
Richard Mueller's solution is therefore to be preferred; but it can be
optimized,
because the size of the array is known before the loop:
UBound( array ) == Len( string ) - 1.
Avoiding the costly ReDim Preserve operation removes a second problem of
this code.
For the empty string the result is set to
Dim arrChars()
That statement creates a fixed array with no elements - something that
doesn't
make sense and can't be handled properly by VBScript (see output line 6).
Using a RegExp is a second way to solve this problem. For simple cases the
overhead may not be worth while; but for more complex requirements the power
of regular expressions may come handy. E.g.: You can treat duplicated
letters
as one element by choosing an appropriate pattern (cf. output line 5).
Code to illustrate:
Dim aTests : aTests = Array( _
Array( "Larry", Array( "L", "a", "r", "r", "y" ) ) _
, Array( "" , Array() ) _
, Array( "L" , Array( "L" ) ) _
)
Dim dicFuncs : Set dicFuncs = CreateObject( "Scripting.Dictionary" )
Set dicFuncs( "RM" ) = GetRef( "RM_S2AC" )
Set dicFuncs( "RMOpt" ) = GetRef( "RM_S2AC_Opt" )
Set dicFuncs( "HZ" ) = GetRef( "HZ_S2AC" )
Set dicFuncs( "ReOne" ) = GetRef( "ReOne_S2AC" )
Set dicFuncs( "ReTwo" ) = GetRef( "ReTwo_S2AC" )
Dim nLine : nLine = 1
Dim aTest
For Each aTest In aTests
Dim sFunc
For Each sFunc In dicFuncs.Keys()
Dim aChars : aChars = dicFuncs( sFunc )( aTest( 0 ) )
Dim vUB
On Error Resume Next
vUB = UBound( aChars )
If 0 <> Err.Number Then vUB = Err.Description
On Error GoTo 0
WScript.Echo Right( " " & nLine, 2 ) _
, ">" & aTest( 0 ) & "<" _
, sFunc _
, "(" & Join( aChars, "," ) & ")" _
, CStr( Join( aChars, "," ) = Join( aTest( 1 ),
"," ) ) _
, TypeName( aChars ) _
, vUB
nLine = nLine + 1
Next
Next
Function RM_S2AC( strValue )
Dim k, arrChars()
For k = 1 To Len(strValue)
ReDim Preserve arrChars(k - 1)
arrChars( k - 1 ) = Mid( strValue, k, 1 )
Next
RM_S2AC = arrChars
End Function
Function RM_S2AC_Opt( sText )
Dim nUB : nUB = Len( sText ) - 1
ReDim aRVal( nUB )
Dim nPos
For nPos = 0 To nUB
aRVal( nPos ) = Mid( sText, nPos + 1, 1 )
Next
RM_S2AC_Opt = aRVal
End Function
Function HZ_S2AC( a )
' Make a copy of the string, adding a space after each item
' so we have something to use as a split character
Dim b : b = ""
Dim i
For i = 1 To Len( a )
b = b & Mid( a, i, 1 ) & " "
Next
' Remove the trailing space
b = Trim( b )
' Split the string into an array
HZ_S2AC = Split( b )
End Function
Function ReOne_S2AC( sText )
ReOne_S2AC = Re_S2AC( sText, "." )
End Function
Function ReTwo_S2AC( sText )
ReTwo_S2AC = Re_S2AC( sText, "(.)\1?" )
End Function
Function Re_S2AC( sText, sPat )
Dim oRE : Set oRE = New RegExp
oRE.Global = True
oRE.Pattern = sPat
Dim oMTS : Set oMTS = oRE.Execute( sText )
ReDim aRVal( oMTS.Count - 1 )
Dim nIdx : nIdx = 0
Dim oMT
For Each oMT In oMTS
aRVal( nIdx ) = oMT.Value
nIdx = nIdx + 1
Next
Re_S2AC = aRVal
End Function
output:
=== splitStr2Chr: split string into array of characters ========
1 >Larry< RM (L,a,r,r,y) Wahr Variant() 4
2 >Larry< RMOpt (L,a,r,r,y) Wahr Variant() 4
3 >Larry< HZ (L,a,r,r,y) Wahr Variant() 4
4 >Larry< ReOne (L,a,r,r,y) Wahr Variant() 4
5 >Larry< ReTwo (L,a,rr,y) Falsch Variant() 3
6 >< RM () Wahr Variant() Index außerhalb des gültigen Bereichs
7 >< RMOpt () Wahr Variant() -1
8 >< HZ () Wahr Variant() -1
9 >< ReOne () Wahr Variant() -1
10 >< ReTwo () Wahr Variant() -1
11 >L< RM (L) Wahr Variant() 0
12 >L< RMOpt (L) Wahr Variant() 0
13 >L< HZ (L) Wahr Variant() 0
14 >L< ReOne (L) Wahr Variant() 0
15 >L< ReTwo (L) Wahr Variant() 0
=== splitStr2Chr: 0 done (00:00:00) ============================
--------------
I agree that you can ReDim the array ahead of time and this is more
efficient than ReDim'ing after processing each character. However, I think
an empty array is useful. If the input string is empty, UBound will be -1,
and the For Each loop will not echo anything, but will also not raise an
error. For example:
=========
Option Explicit
Dim strValue, strChar, k, arrChars()
strValue = "Larry"
strValue = ""
ReDim arrChars(Len(strValue) - 1)
For k = 1 To Len(strValue)
strChar = Mid(strValue, k, 1)
arrChars(k - 1) = strChar
Next
For Each strChar In arrChars
Wscript.Echo strChar
Next
--
Richard Mueller
MVP Directory Services
Hilltop Lab -
http://www.rlmueller.net
--