WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Arrays
plus
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Array and Lists - Split and Join

 Keywords: Keywords: Split Join Array Delimit Delimiter String Parse List File Path Arrayize ArrayFromStr ArraytoStr udfArrayFromList udfArraytoList udfArrayFromDelimStr udfArrayToDelimStr 

Multiple Dimensional Arrays

;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayFromList (strList, strDelimiter)
If strList == "" Then Return ArrDimension (0) ; Return dim-0 array with no element.
If strDelimiter == "" Then Return ArrayFromStr (strList) ; Return dim-1 array with one character per array element.

arrD = ArrDimension (6)
ArrInitialize (arrD, "")

arrE = ArrDimension (6)
ArrInitialize (arrE, 0)

arrE [0] = Min (5, StrLen (strDelimiter))
arrD [1] = StrSub (strDelimiter, 1, 1)
arrE [1] = ItemCount (strList, arrD [1])
strItem = ItemExtract (1, strList, arrD [1])
For intI = 2 To arrE [0]
   arrD [intI] = StrSub (strDelimiter, intI, 1)
   arrE [IntI] = ItemCount (strItem, arrD [intI])
   strItem = ItemExtract (1, strItem, arrD [intI])
Next

arrArray = ArrDimension (arrE[1], arrE[2], arrE[3], arrE[4], arrE[5])

Switch arrE [0]
Case 1
   For intD1 = 1 To arrE [1]
      arrArray [intD1 - 1] = ItemExtract (intD1, strList, arrD [1])
   Next
   Break
Case 2
   For intD1 = 1 To arrE [1]
      strItem1 = ItemExtract (intD1, strList, arrD [1])
      For intD2 = 1 To arrE [2]
         arrArray [intD1 - 1, intD2 - 1] = ItemExtract (intD2, strItem1, arrD [2])
      Next
   Next
   Break
Case 3
   For intD1 = 1 To arrE [1]
      strItem1 = ItemExtract (intD1, strList, arrD [1])
      For intD2 = 1 To arrE [2]
         strItem2 = ItemExtract (intD2, strItem1, arrD [2])
         For intD3 = 1 To arrE [3]
            arrArray [intD1 - 1, intD2 - 1, intD3 - 1] = ItemExtract (intD3, strItem2, arrD [3])
         Next
      Next
   Next
   Break
Case 4
   For intD1 = 1 To arrE [1]
      strItem1 = ItemExtract (intD1, strList, arrD [1])
      For intD2 = 1 To arrE [2]
         strItem2 = ItemExtract (intD2, strItem1, arrD [2])
         For intD3 = 1 To arrE [3]
            strItem3 = ItemExtract (intD3, strItem2, arrD [3])
            For intD4 = 1 To arrE [4]
               arrArray [intD1 - 1, intD2 - 1, intD3 - 1, intD4 - 1] = ItemExtract (intD4, strItem3, arrD [4])
            Next
         Next
      Next
   Next
   Break
Case 5
   For intD1 = 1 To arrE [1]
      strItem1 = ItemExtract (intD1, strList, arrD [1])
      For intD2 = 1 To arrE [2]
         strItem2 = ItemExtract (intD2, strItem1, arrD [2])
         For intD3 = 1 To arrE [3]
            strItem3 = ItemExtract (intD3, strItem2, arrD [3])
            For intD4 = 1 To arrE [4]
               strItem4 = ItemExtract (intD4, strItem3, arrD [4])
               For intD5 = 1 To arrE [5]
                  arrArray [intD1 - 1, intD2 - 1, intD3 - 1, intD4 - 1, intD5 - 1] = ItemExtract (intD5, strItem4, arrD [5])
               Next
            Next
         Next
      Next
   Next
   Break
EndSwitch

Return arrArray
;..........................................................................................................................................
; This UDF "udfArrayFromList" returns a dim-1 .. dim-5 array, whose array elements are filled
; by iterative separating the given input string into chunks of substrings.
;
; The input string is a serialized string list representation of a dim-1 .. dim-5 array.
; The elements are delimited by 1 .. 5 delimiter string characters accordingly to their array dimension.
;
; If the given strList is empty, then the function returns a dim-0 array with no element.
;
; If the given strDelimiter is empty, then the function returns a dim-1 array with each element filled
; with one character of the given strList, which has been splitted into separate chars.
;
; Syntax:
; arr:Array = udfArrayFromList (str:String, str:Delimiter)
;
; Detlev Dalitz.20030225.20090520.20110123.
;..........................................................................................................................................
;
; Example 1:
;
;   ; Create dim-2 array.
;   ; One Element        = "o".
;   ; Dim2 = 2 x Element = "o+o" ; Delim "+".
;   ; Dim1 = 3 x Dim1    = "o+o=o+o=o+o" ; Delim "=".
;   ;
;   ;     | 0  1
;   ;   --+------
;   ;   0 | a  b
;   ;   1 | c  d
;   ;   2 | e  f
;
;   intElementsShouldBe = 3 * 2 ; 6.
;
;   strList = "o+o=o+o=o+o"
;   strDelimiter = "=+" ; Dimensions 1-2.
;
;   intElementsAre = StrLen (StrClean (strList, strDelimiter, "", @TRUE, 1)) ; 6.
;
;   arrA = udfArrayFromList (strList, strDelimiter)
;
;   arrB = ArrDimension (8)
;   arrB[0] = ArrInfo (arrA, -1) ; Validity of the array. 1=@TRUE valid, 0=@FALSE invalid.
;   arrB[1] = ArrInfo (arrA, 0)  ; Number of dimensions in the array.
;   arrB[2] = ArrInfo (arrA, 1)  ; Number of elements in dimension 1.
;   arrB[3] = ArrInfo (arrA, 2)  ; Number of elements in dimension 2.
;   arrB[4] = ArrInfo (arrA, 3)  ; Number of elements in dimension 3.
;   arrB[5] = ArrInfo (arrA, 4)  ; Number of elements in dimension 4.
;   arrB[6] = ArrInfo (arrA, 5)  ; Number of elements in dimension 5.
;   arrB[7] = ArrInfo (arrA, 6)  ; Number of elements in the entire array.
;
;   strListInfo = udfArrayToList (arrB, "|") ; 1|2|3|2|0|0|0|6.
;
;..........................................................................................................................................
;
; Example 2:
;
;   ; Create dim-5 array.
;   ; One Element        = "o".
;   ; Dim5 = 2 x Element = "o+o" ; Delim "+".
;   ; Dim4 = 4 x Dim5    = "o+o=o+o=o+o=o+o" ; Delim "=".
;   ; Dim3 = 3 x Dim4    = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; Delim "/".
;   ; Dim2 = 2 x Dim3    = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; Delim "|".
;   ; Dim1 = 2 x Dim2    = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o@o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; Delim "@".
;
;   intElementsShouldBe = 2 * 2 * 3 * 4 * 2 ; 96.
;
;   strList = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o@o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o"
;   strDelimiter = "@|/=+" ; Dimensions 1-2-3-4-5.
;
;   intElementsAre = StrLen (StrClean (strList, strDelimiter, "", @TRUE, 1)) ; 96.
;
;   arrA = udfArrayFromList (strList, strDelimiter)
;
;   arrB = ArrDimension (8)
;   arrB[0] = ArrInfo (arrA, -1) ; Validity of the array. 1=@TRUE valid, 0=@FALSE invalid.
;   arrB[1] = ArrInfo (arrA, 0)  ; Number of dimensions in the array.
;   arrB[2] = ArrInfo (arrA, 1)  ; Number of elements in dimension 1.
;   arrB[3] = ArrInfo (arrA, 2)  ; Number of elements in dimension 2.
;   arrB[4] = ArrInfo (arrA, 3)  ; Number of elements in dimension 3.
;   arrB[5] = ArrInfo (arrA, 4)  ; Number of elements in dimension 4.
;   arrB[6] = ArrInfo (arrA, 5)  ; Number of elements in dimension 5.
;   arrB[7] = ArrInfo (arrA, 6)  ; Number of elements in the entire array.
;
;   strListInfo = udfArrayToList (arrB, "|") ; 1|5|2|2|3|4|2|96.
;
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayUnloadToFile (arrArray, strFilename)
If !ArrInfo (arrArray, -1) Then Return 0 ; No array.
If !ArrInfo (arrArray, 6) Then Return 0 ; No elements.

arrArrInfo = ArrDimension (8)
arrArrInfo[0] = "ArrInfo;-1;{0};Validity of the array. 1=@TRUE valid, 0=@FALSE invalid."
arrArrInfo[1] = "ArrInfo;0;{1};Number of dimensions in the array."
arrArrInfo[2] = "ArrInfo;1;{2};Number of elements in dimension 1."
arrArrInfo[3] = "ArrInfo;2;{3};Number of elements in dimension 2."
arrArrInfo[4] = "ArrInfo;3;{4};Number of elements in dimension 3."
arrArrInfo[5] = "ArrInfo;4;{5};Number of elements in dimension 4."
arrArrInfo[6] = "ArrInfo;5;{6};Number of elements in dimension 5."
arrArrInfo[7] = "ArrInfo;6;{7};Number of elements in the entire array."

intDims = ArrInfo (arrArray, 0)
strIndexFill = StrFill (",0", 2 * (5 - intDims))
arrD = ArrDimension (6)
arrE = ArrDimension (6)
For intD = 1 To 5
   arrE[intD] = Max (ArrInfo (arrArray, intD) - 1, 0)
Next

hdlFW = FileOpen (strFilename, "WRITE")

strBOM = "" ; BOM (EF BB BF) for Unicode UTF-8.
FileWrite (hdlFW, strBOM : '<?xml version="1.0" encoding="utf-8" standalone="yes"?>') ; XML declaration line with leading BOM (EF BB BF).
FileWrite (hdlFW, "<ARRAY>")            ; Open node "ARRAY".
FileWrite (hdlFW, "<ARRINFO><![CDATA[") ; Open node "ARRINFO".
; Write data.
For intI = 0 To 7
   FileWrite (hdlFW, StrReplace (arrArrInfo[intI], "{" : intI : "}", ArrInfo (arrArray, intI - 1)))
Next
FileWrite (hdlFW, "]]></ARRINFO>")      ; Close node "ARRINFO".
FileWrite (hdlFW, "<ARRDATA><![CDATA[") ; Open node "ARRDATA".
; Write data.
For intD1 = 0 To arrE[1]
   arrD[1] = intD1
   For intD2 = 0 To arrE[2]
      arrD[2] = intD2
      For intD3 = 0 To arrE[3]
         arrD[3] = intD3
         For intD4 = 0 To arrE[4]
            arrD[4] = intD4
            For intD5 = 0 To arrE[5]
               arrD[5] = intD5
               strIdx = ""
               For intD = 1 To intDims
                  strIdx = ItemInsert (arrD[intD], -1, strIdx, ",")
               Next
               strArrIndex = strIdx : strIndexFill
               intVarType = VarType (arrArray [%strIdx%])
               If intVarType
                  strOut = ChrStringToUnicode ("" : arrArray [%strIdx%])
                  intPrevCodePage = ChrSetCodepage (65001)
                  FileWrite (hdlFW, strArrIndex : ";" : intVarType : ";" : strOut)
                  ChrSetCodepage (intPrevCodePage)
               Else
                  FileWrite (hdlFW, strArrIndex : ";" : intVarType : ";")
               EndIf
            Next
         Next
      Next
   Next
Next
FileWrite (hdlFW, "]]></ARRDATA>") ; Close node "ARRDATA".
FileWrite (hdlFW, "</ARRAY>")      ; Close node "ARRAY".
hdlFW = FileClose (hdlFW)
Return FileSizeEx (strFilename)
;..........................................................................................................................................
; This function "udfArrayUnloadToFile" creates a specific array definition textfile (xml) from array,
; which can be used to load data back into an array by function "udfArrayLoadFromFile".
;
; Detlev Dalitz.20010731.20020828.20030222.20090528.20100122.20100125.20110123.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


; Test.

strMsgTitle = "Demo: udfArrayFromList (strList, strDelimiter)"

:Test1
strList = ""
strDelimiter = "@|"
arrArray = udfArrayFromList (strList, strDelimiter)
GoSub DisplayResult


:Test2
strList = "Teststring"
strDelimiter = ""
arrArray = udfArrayFromList (strList, strDelimiter)
GoSub DisplayResult


:Test3
strList = "one two three four"
strDelimiter = " "
arrArray = udfArrayFromList (strList, strDelimiter)
GoSub DisplayResult


:Test4
strList = "1|apple@2|pear@3|banana"
strDelimiter = "@|"
arrArray = udfArrayFromList (strList, strDelimiter)
GoSub DisplayResult


:Test5
strList = "1|apple@2|pear@3|banana@" ; Trailing dim1 delimiter causes 'trailing' empty array cells.
strDelimiter = "@|"
arrArray = udfArrayFromList (strList, strDelimiter)
GoSub DisplayResult


:Test5
strList = "o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o|o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o|o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o@o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o|o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o|o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o/o+o=o+o=o+o"
strDelimiter = "@|/=+"
arrArray = udfArrayFromList (strList, strDelimiter)
GoSub DisplayResult

Exit

;------------------------------------------------------------------------------------------------------------------------------------------
:DisplayResult
strMsgTitle = "Demo: udfArrayFromList (strList, strDelimiter)"

strFilename = ShortCutDir ("Local Settings", 0, 1) : "Temp\Demo.udfArrayFromList.txt"

strWindowNP = ""
If udfArrayUnloadToFile (arrArray, strFilename)
   blnResult = RunZoom ("notepad.exe", strFilename)
   strWindowNP = WinGetactive ()
   blnResult = FileDelete (strFilename)
EndIf

intDims = ArrInfo (arrArray, 0) ; Number of dimensions in the array.
intElements = ArrInfo (arrArray, 6) ; Number of elements in the entire array.
strMsgText = "strList      = " : strList : @LF
strMsgText = strMsgText : "strDelimiter = " : strDelimiter : @LF
strMsgText = strMsgText : "intDims      = " : intDims : @LF
strMsgText = strMsgText : "intElements  = " : intElements : @LF

IntControl (63, 300, 300, 700, 700) ; Sets coordinates for AskFileText, AskItemList and AskTextBox windows.
IntControl (28, 1, 0, 0, 0)         ; Selects system font used in list boxes. p1=1=fixed pitch font.
AskItemlist (strMsgTitle, strMsgText, @LF, @UNSORTED, @SINGLE)

:CANCEL
If IsDefined (strWindowNP) Then If strWindowNP != "" Then If WinExist (strWindowNP) Then WinClose (strWindowNP)

Return ; from GoSub DisplayResult.
;------------------------------------------------------------------------------------------------------------------------------------------


VB Split and Join

;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfVBSplit (strExpression, strDelimiter, intCount, intCompare)
objSC = ObjectCreate ("MSScriptControl.ScriptControl")
objSC.Language = "VBScript"
objSC.AddCode(: "Function F(P1,P2,P3,P4)" : @LF : 'F=Split(P1,P2,P3,P4)' : @LF : "End Function")
Return objSC.Run(: "F", strExpression, strDelimiter, intCount, intCompare)
;..........................................................................................................................................
; This UDF udfVBSplit() returns an one-dimensional array containing a specified number of substrings.
;
; Parameter:
; strExpression
;    String expression containing substrings and delimiters.
;    If expression is a zero-length string, then an empty array will be returned, that is, an array with no elements and no data.
; strDelimiter
;    String used to identify substring limits.
;    If delimiter is a zero-length string, then a single-element array containing the entire expression string is returned.
; intCount
;    Number of substrings to be returned; -1 indicates that all substrings are returned.
; intCompare
;    Numeric value indicating the kind of comparison to use when evaluating substrings.
;       0 ... Perform a binary comparison.
;       1 ... Perform a textual comparison.
;..........................................................................................................................................
; (c)Detlev Dalitz.20110608.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfVBJoin (arrArray, strDelimiter)
objSC = ObjectCreate ("MSScriptControl.ScriptControl")
objSC.Language = "VBScript"
objSC.AddCode(: "Function F(P1,P2)" : @LF : 'F=Join(P1,P2)' : @LF : "End Function")
Return objSC.Run(: "F", arrArray, strDelimiter)
;..........................................................................................................................................
; This UDF udfVBJoin() returns a string created by joining a number of substrings contained in an array.
;
; Parameter:
; arrArray
;    One-dimensional array containing substrings to be joined.
; strDelimiter
;    Any string, used to separate the substrings in the returned string.
;    If Delimiter is a zero-length string, then all items in the list are concatenated with no delimiters.
;..........................................................................................................................................
; (c)Detlev Dalitz.20110608.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


DirChange (DirScript ())

; Test Split.

:Test11
strTest1 = "WB|with|VBScript|is|fun!"
arrTest1 = udfVBSplit (strTest1, "|", -1, 1)

ForEach strItem In arrTest1
   Pause ("Test udfVBSplit (1)", strItem)
Next


:Test12
strTest2 = "WB|wisth|VBScrispt|is|fun!"
arrTest2 = udfVBSplit (strTest2, "Is", -1, 1)

ForEach strItem In arrTest2
   Pause ("Test udfVBSplit (2)", strItem)
Next


:Test13
strTest3 = "WB|with|VBScript|is|fun!"
arrTest3 = udfVBSplit (strTest3, "Is", -1, 0)

ForEach strItem In arrTest3
   Pause ("Test udfVBSplit (3)", strItem)
Next


; Test Join.

:Test21
strList1 = udfVBJoin (arrTest1, " - ")

Pause ("Test udfVBJoin (1)", strList1)


:Test22
strList2 = udfVBJoin (arrTest1, "")

Pause ("Test udfVBJoin (2)", strList2)


:Test23
strList3 = udfVBJoin (arrTest1, "|")

Pause ("Test udfVBJoin (3)", strList3)

:CANCEL
Exit


Single Dimensional Arrays

; I couldn't find a similar command for vbscript's split, whether it doesn't exist
; or my inept searching skills couldn't find it, so wrote a function to do it.  Since I'd
; also need to rejoin the string at some point, i made the arrJoin function while I
; was at it.  In hindsight, I probably could have use lists, but I'm coming from
; vbscriptland so have the array mentality.  Hopefully others will get some use out of it.
;
; Developers: suprnova74 / D.Falk  06/06/2011
;
#DefineFunction udfArrayFromList(strSource, strDelim)
   ;  Splits a string into an array, splitting by a delimiter string (list)
   ;  SEE ALSO: ARRAYIZE()
   If strDelim == "" || StrLen(strDelim)>1
      Pause('Notice','Invalid delimiter specified')
      Exit
   EndIf
   length=StrLen(strSource)
   start = 1
   count=0
   While @TRUE
      finish = StrScan(strSource, strDelim, start, @FWDSCAN)
      If finish == 0
         Break
      Else
         count = count+1
         param%count% = StrSub(strSource, start, finish - start)
         start=finish+1
        ; Message("Parameter number %count% is", param%count%)
         If finish == length Then Break
      EndIf
   EndWhile
   If start <= length
      finish = length+1
      count = count+1
      param%count% = StrSub(strSource, start, finish - start)
     ; Message("Parameter number %count% is", param%count%)
   EndIf
   param0 = count
   ;Message("Parameter count is",param0)
   If param0 == 0
      Pause('Notice','Invalid string specified')
      Exit
   EndIf
   arrSplit = ArrDimension(param0)

   For ctr = 1 To param0
     arrsplit[ctr - 1] = param%ctr%
   Next
   Return(arrSplit)
#EndFunction

#DefineFunction udfArrayToList(arrToJoin,strDelim)
   ; Joins an array into a string (list), padding with a delimiter in between each element
   strJoined = ""

   ubound = ArrInfo ( arrToJoin, 1 ) -1
   For ctr = 0 To ubound
      If ctr < ubound
         strJoined=StrCat(strJoined,arrToJoin[ctr],strDelim)
      Else
         strJoined=StrCat(strJoined,arrToJoin[ctr])
      EndIf

   Next
   Return (strJoined)
#EndFunction



;Usage examples:

; File Path Test
arrtest = udfArrayFromList("c:\path\path 2\path3\file.txt", "\")
Message("test", udfArrayToList(arrtest, "\"))

; UNC Test
arrtest = udfArrayFromList("\\share\path\path 2\path3\file.txt", "\")
Message("test", udfArrayToList(arrtest, "\"))

; Root Drive Test
arrtest = udfArrayFromList("c:\", "\")
Message("test", udfArrayToList(arrtest, "\"))

; No Delimiter in String Test
arrtest = udfArrayFromList("abcdefghijklmnopqrstuvwxyz", "\")
Message("test", udfArrayToList(arrtest, "\"))

; No Delimiter Test
arrtest = udfArrayFromList("abcdefghijklmnopqrstuvwxyz", "")
Message("test", udfArrayToList(arrtest, "\"))

; Blank String Test
arrtest = udfArrayFromList("", "\")
Message("test", udfArrayToList(arrtest, "\"))



Article ID:   W17653
Filename:   Array and Lists - Split and Join.txt
File Created: 2011:06:08:15:31:56
Last Updated: 2011:06:08:15:31:56