Luca Ruggeri
Luca Ruggeri

Reputation: 121

Sort a String array

I have as input the string in the below format

"[1_5,3,7,1],[1_2,4,1,9],[],[1_1,,4,,,9,2]"

What I need to obtain is the same string but with the number after the _ sorted:

"[1_1,3,5,7],[1_1,2,4,9],[],[1_1,2,4,9,,,]"
Dim tmprequestedArea_selectionAreaIn As String = "[1_5,3,7,1],[1_2,4,1,9],[],[1_1,,4,,,9,2]"

tmprequestedArea_selectionAreaIn = Regex.Replace(requestedArea_selectionAreaIn,"\],\[","#")
tmprequestedArea_selectionAreaIn = Regex.Replace(tmprequestedArea_selectionAreaIn,"\[|\]","")

bracList.AddRange(tmprequestedArea_selectionAreaIn.Split(New Char() {"#"c}, StringSplitOptions.None ))

If sortNumber Then 
    'Split braclist by _ and puts the value in strList 
    'If after _ is only one number put only that number, else split it by char "," and put in strList the join of the split by , array
    'Sort the array
    'in previous example strList will contain a,b,c in position 0 and _d_f (instead of f,d) in position 1
    For i As Integer = 0 To bracList.Count -1
        Dim tmp As String()
        Dim tmpInt As New System.Collections.Generic.List(Of Integer) 
        If Not(String.IsNullOrEmpty(bracList(i))) Then 
            Dim tmpRequested As String = bracList(i).Split(New Char() {"_"c})(0)
            Dim tmpSelection As String = bracList(i).Split(New Char() {"_"c})(1)

        If tmpSelection.Contains(",") Then
            tmp = tmpSelection.Split(New Char() {","c})
            For j As Integer = 0 To tmp.Length -1
                tmpInt.Add(Convert.toInt32(tmp(j)))
            Next
            tmpInt.Sort
            strList.Add("["  + tmpRequested + "_" + String.Join(",",tmpInt ) + "]")
        Else
            strList.Add("[" +  tmpRequested + "_" + tmpSelection + "]" )
        End If
        Else
            strList.Add("[]")
        End If
    Next i

I'm looking for a better way to manage it.

Upvotes: 1

Views: 125

Answers (1)

Jimi
Jimi

Reputation: 32248

Try this, as a possible substitute for what you're doing now.

Given this input string:

Dim input As String = "[1_5,3,7,1],[1_2,4,1,9],[],[1_1,,4,,,9,2]"

Note: this will also deal with decimal values without changes. E.g.,

"[1_5.5,3.5,7,1],[1_2.564,4,2.563,9],[],[1_1,,4.23,,,9.0,2.45]"

You can extract the content of the brackets with this pattern: \[(.*?)\] and use Regex.Matches to return a MatchCollection of all the substrings that match the pattern.

Then use a StringBuilder as a container to rebuild the string while the parts are being treated.

Imports System.Linq
Imports System.Text.RegularExpressions

Dim pattern As String = "\[(.*?)\]"
Dim matches = Regex.Matches(input, pattern, RegexOptions.Singleline)
Dim sb As New StringBuilder()

For Each match As Match In matches
    Dim value As String = match.Groups(1).Value
    If String.IsNullOrEmpty(value) Then
        sb.Append("[],")
        Continue For
    End If
    Dim sepPosition As Integer = value.IndexOf("_"c) + 1
    sb.Append("[" & value.Substring(0, sepPosition))
    Dim values = value.Substring(sepPosition).Split(","c)
    sb.Append(String.Join(",", values.Where(Function(n) n.Length > 0).OrderBy(Function(n) CDec(n))))
    sb.Append(","c, values.Count(Function(n) n.Length = 0))
    sb.Append("],")
Next

Dim result As String = sb.ToString().TrimEnd(","c)

If you don't know about LINQ, this is what it's doing:

String.Join(",", values.Where(Function(n) n.Length > 0).OrderBy(Function(n) CDec(n)))

values is an array of strings, generated by String.Split().

values.Where(Function(n) n.Length > 0): creates an Enumerable(Of String) from values Where the content, n, is a string of length > 0.
I could have written values.Where(Function(n) Not String.IsNUllOrEmpty(n)).

.OrderBy(Function(n) CDec(n))): Orders the resulting Enumerable(Of String) using the string value converted to Decimal and generates an Enumerable(Of String), which is passed back to String.Join(), to rebuild the string, adding a char (","c) between the parts.

values.Count(Function(n) n.Length = 0): Counts the elements of values that have Length = 0 (empty strings). This is the number of empty elements that are represented by a comma, appended at the end of the partial string.

Upvotes: 3

Related Questions