Moving Comma-seperated string into a 2d array.

mike55

Contributor
Joined
Mar 26, 2004
Messages
727
Location
Ireland
Hi

I am using the following code to obtain a response from a web page:
Code:
 objRequest = System.Net.HttpWebRequest.Create(HttpPaymentRequestUrl(receiptCode))
            objResponse = objRequest.GetResponse()

I am using a StreamReader to convert the return into a string:
Code:
Dim sr As New StreamReader(objResponse.GetResponseStream())
result = sr.ReadToEnd

I want to take the result returned from the web request and put it into an array, preferabily a 2d array.

Here is a sample of the web request:

Here are the results that I get back:
Receipt,Identifier,Amount,Auth,ReasonCode,Status,Batch
21051541119,test,0.2,REFERRAL A,02,F,

I know that I can do it by doing a loops to determine how many "," are in the string, followed by a loop that gets each value and inserts it into the array.

Is there instead a more effective approach, I know that when you want to convert an array to a comma-seperated string you can use the command:
Code:
String.Join(",", arrayName)

Is there any method that does the reverse? Alternatively, can I use datatables?

Mike55.
 
Last edited:
Visual Basic:
dim s as string = "One, Two, Three"
dim x() as string = s.Split(",")

The above will return an array of strings - one element per value between the separator specified.
 
Visual Basic:
dim s as string = "One, Two, Three"
dim x() as string = s.Split(",")

Yea, came across the above code else where and used it. I also had to use a char() to store the split elements as when I did a quick watch on the string, I found that there was also a carriage return. Given that the carriage return indicates a new line is there any way to split the string into a 2d array?

Mike55.
 
2D array vs jagged array

There is no simple way of using Split to obtain a 2D array. If there are an equal number of elements on each line, then it could be achieved by using the first line as a size guide:

Untested code:

Visual Basic:
Dim values(,) As String
Dim lines() As String
Dim parts() As String

'Get lines
lines = myString.Split(ControlChars.Lf) 'Use appropriate line separator
parts = lines(0).Split(","c)

'Resize output array
ReDim values(lines.Count - 1, parts.Count - 1)

For i As Integer = 0 To lines.Count - 1

    'Get values of this line
    parts = lines(i).Split(","c)

    'Copy parts into 2D array
    For j As Integer = 0 To parts.Count - 1
        values(i, j) = parts(j)
    Next
Next

However, if the number of values on each line varies, you are probably best using a jagged array (infact I would recommend this either way). This basically consists of an array of arrays:

Visual Basic:
Dim values()() As String
Dim lines() As String

'Get lines
lines = myString.Split(ControlChars.Lf) 'Use appropriate line separator

'Resize output array
ReDim values(lines.Count - 1)

For i As Integer = 0 To lines.Count - 1
    'Get values for this line
    values(i) = lines(i).Split(","c)
Next

Now the jth value on line i can be referenced by values(i)(j).

Good luck :cool:
 
Here is the final version of the code, it is optimised for dealing with the Malta based payment gateway endeavour:
Code:
        Private Function GetParameterValue(ByVal csString As String, ByVal searchValue As String) As String
            Dim values()() As String
            Dim lines() As String

            'Get lines
            lines = csString.Split(System.Environment.NewLine) 'Use appropriate line separator

            'Resize output array
            'Dim i As Int16 = 0
            'While i <= (lines.Length - 1)

            'End While
            'ReDim values(lines.Length - 1)
            ReDim values(0)

            Dim position As Int16 = 0

            'Take the return and put it into a 2d array.
            For i As Integer = 0 To (lines.Length - 1)
                Select Case String.IsNullOrEmpty(lines(i).ToString)
                    Case False
                        'Check to determine if the line contains valid data, some lines come back with a character with the ascii code 10
                        Select Case lines(i).Contains(",")
                            Case True

                                'Increase the size of the array if needed.
                                Select Case position
                                    Case 0
                                        'do nothing
                                    Case Is > 0
                                        ReDim Preserve values(position)
                                End Select

                                'Get values for this line
                                values(position) = lines(i).Split(","c)
                                position += 1

                            Case False
                                'do nothing
                        End Select

                    Case True
                        'do nothing
                End Select

            Next

            'In the event that the first character of the first value of each line has an ASCII value of 10, remove that character.
            For i As Integer = 0 To (values.Length - 1)
                Select Case Asc(values(i)(0).Chars(0)).ToString
                    Case "10"
                        values(i)(0) = values(i)(0).Remove(0, 1)
                End Select
            Next

            'Begin looking for the searchValue
            Dim parameterValue As String = Nothing
            Dim aLength As Int16 = 0
            Dim aHeight As Int16 = 0
            Dim pos As Int16 = 0

            'Get the length of the array and begin iterating though it untill parameter located.
            aLength = values(0).Length
            aHeight = values.Length

            While pos < aLength - 1
                If values(0)(pos).ToLower = searchValue.ToLower Then
                    parameterValue = values(aHeight - 1)(pos)
                    Exit While
                End If
                pos += 1
            End While

            Return parameterValue
        End Function

Alternatively, if anyone wants to refactor the code, fire away.

Mike55.
 
Refactoring

Rather than constantly resizing an array, I would suggest using a List(Of String()) (from System.Collections.Generic). This will be more efficient and will deal with the resizing of the collection automatically.

For the second For loop, you could use the TrimStart method of the string, rather than checking the first character:

Visual Basic:
For Each line As String() In values
    line(0) = line(0).TrimStart(ControlChars.Cr)
Next

However, from the looks of your last For loop, you're only interested in values taken from the last line of data, using the first line as column guide. This would mean there is no real need to store every other line in an array or collection, you may as well just parse the first and last lines:

Visual Basic:
Dim lines() As String
Dim colnames() As String
Dim lastrow() As String

'Get lines
lines = csString.Split(Environment.NewLine)

'Get column names
For Each line As String In lines
    If (line.Contains(",")) Then
        colnames = line.Split(",")
        Exit For
    End If
Next

'Get last line (as above, searching backwards)
Array.Reverse(lines)
For Each line As String In lines
    If (line.Contains(",")) Then
        lastrow = line.Split(",")
        Exit For
    End If
Next

'Find appropriate index in colnames here, then take value from lastrow

Good luck :cool:
 
Back
Top