Home > Back-end >  Easier Way (Linq) to Convert List Using Split
Easier Way (Linq) to Convert List Using Split

Time:12-31

I could really use some help here.

I have a List(Of String) that contains the following:

A/a
A/b
A/c
B/a
B/b
B/c
C/a
C/b
C/c
..etc.

I am trying to create controls in a TableLayoutPanel grouped by the first letter such that the layout looks something like this.

Heading A

Label a | Textbox a
Label b | Textbox b
Label c | Textbox c

Heading B

Label a | Textbox a
Label b | Textbox b
Label c | Textbox c

Heading C

Label a | Textbox a
Label b | Textbox b
Label c | Textbox c

My current code sorts the List and creates the controls:

 For Each item In _List

                    TableLayoutPanel1.Controls.Add(New Label With {
                           .Name = cc.ToString,
                           .Text = SplitContentControl(cc.ToString, ""),
                           .Height = 20,
                           .Font = New Font("Segoe UI", 12,
                    FontStyle.Bold)
                                                  })


                    TableLayoutPanel1.Controls.Add(New TextBox With {.Height = 20,
                    .Font = New Font("Segoe UI", 12,
                    FontStyle.Bold)})
 Next 

I have tried creating a Dictionary(Of String, String) like so:

Dim dict As Dictionary(Of String, String) = ccs.ToDictionary(Function(x) x.split("/")(0), Function(y) y.split("/")(1))

but of course can't do that as this generates duplicates.

I've also tried creating a new List(Of ControlID) using the Split("/") and Lambda expression where ControlID is the Class

Public Class ControlID
 Public ControlHead as String
 Public ControlName as String
End Class

but I just can't seem to get the Lambda to work for me no matter what I tried.

If anyone has a solution please help. I'd be very grateful.

CodePudding user response:

Maybe this will give you some ideas...

Private Sub Test()
    Dim l As List(Of String)
    'some data
    l = (From s In {"B", "A", "C"}
            From sm In {"c", "b", "a"}
            Select s & "/" & sm).ToList

    Dim ctrlGRPS

    ctrlGRPS = From s In l
                 Let c = New ControlID(s)
                 Select c Order By c.ControlName Order By c.ControlHead
                 Group By h = c.ControlHead
                 Into HeadGrp = Group

    For Each head In ctrlGRPS
        For Each ctrl In head.HeadGrp
            Stop 'look at ctrl
        Next
    Next
End Sub

Public Class ControlID
    Public ControlHead As String
    Public ControlName As String
    Public Sub New(s As String)
        Dim p() As String = s.Split("/"c)
        Me.ControlHead = p(0)
        Me.ControlName = p(1)
    End Sub
End Class

CodePudding user response:

Unless I misunderstand your question, the following should work:

Dim controlIds As IEnumerable(Of ControlID) = ccs
    .Select(Function(x) New ControlID With { .ControlHead = x.split("/")(0), .ControlName = x.split("/")(1) })

However, it'd be easier to read if you made a method that created a ControlID object, like this:

Private Function ParseControlId(value As String) As ControlID
    Dim parts() As String = value.Split("/")
    Return New ControlID With { .ControlHead = parts(0), .ControlName = parts(1) }
End Function

Then, in your LINQ, you could reference that function rather than a lambda:

Dim controlIds As IEnumerable(Of ControlID) = ccs.Select(AddressOf ParseControlID)
  • Related