Greatchap
Greatchap

Reputation: 382

Manipulating List of Structure Array

I have a structure for example:

Structure User
 Dim Name as string
 Dim ID as Short
 Dim Email as string
End Structure

Now the main array declaration is : Dim Client as new list of User

This new list of array holds all the records. Now how to do the following without using loop such as :
1) I need to populate all distinct name into combo box. If it was string array I could have done

Combobox1.addrange(tmpstring.distinct.toarray)

However because this is a structure of a type (e.g. user) what to do ?

2) How to populate only one set of field data into array using linq. For e.g. if I do Dim A = from b in Client where b.id>0 ' then all array items are returned. How to get only id ?

Thank you.

Upvotes: 0

Views: 453

Answers (2)

Jimi
Jimi

Reputation: 32248

A List(Of Class) (a reference type) is more flexible than a Structure (a value type).

Using a List(Of Structure):

Dim Clients As New List(Of User)

Structure User
    Dim Name As String
    Dim ID As Short
    Dim Email As String
End Structure

'Add some elements to it
Clients.Add(New User With {.Name = "User1", .ID = 1, .Email = "Email1"})
Clients.Add(New User With {.Name = "User2", .ID = 2, .Email = "Email2"})
Clients.Add(New User With {.Name = "User3", .ID = 3, .Email = "Email3"})

To fill up a ComboBox list, you could:

'Fill it with the whole list
ComboBox1.Items.AddRange(Clients.Select(Function(c) c.Name).ToArray)

'Or filter it using a range of values
Dim SublistClient As New List(Of User)
SublistClient.AddRange(Clients.Select(Function(c) c).Where(Function(c) (c.ID > 1 And c.ID < 3)))

ComboBox1.Items.AddRange(SublistClient.Select(Function(c) c.Name).ToArray)

To get the Item values when a User selects it from the list:

Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
    Dim SelectedUser As User = Clients(ComboBox1.SelectedIndex)
    Console.WriteLine("Name: {0}, ID: {1}, Email: {2}", SelectedUser.Name, SelectedUser.ID, SelectedUser.Email)
End Sub

Using a List(Of Class)

Dim Clients As New List(Of User)

Class User
   Public Property Name As String
   Public Property ID As Short
   Public Property Email As String
End Class

  'You can add items to the list in the same way, nothing will change here
  Clients.Add(New User With {.Name = "User1", .ID = 1, .Email = "Email1"})
  Clients.Add(New User With {.Name = "User2", .ID = 2, .Email = "Email2"})
  Clients.Add(New User With {.Name = "User3", .ID = 3, .Email = "Email3"})

Now you can fill you ComboBox using its .DataSource property

  'Add the whole List as the ComboBox `.DataSource`
  ComboBox1.DataSource = Clients

  'Or filter it using a range of values
  ComboBox1.DataSource = (Clients.Select(Function(c) c).Where(Function(c) (c.ID > 1 And c.ID < 3))).ToList()

  'Or from a specific value up or down
  ComboBox1.DataSource = (Clients.Select(Function(c) c).Where(Function(c) c.ID > 1)).ToList()

  'This gives you extended options when you have to present your data
  'or evaluate the result of a choice
  ComboBox1.DisplayMember = "Name"
  ComboBox1.ValueMember = "ID"

'The user choice is evaluated more or less in the same manner
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
   Dim SelectedUser As User = CType(ComboBox1.SelectedItem, User)
   Console.WriteLine("Name: {0}, ID: {1}, Email: {2}", SelectedUser.Name, SelectedUser.ID, SelectedUser.Email)
End Sub

Upvotes: 1

Lightbringer
Lightbringer

Reputation: 819

1) I am not that familiar with VB, so here is the solution in C#:

var names = Client
  .Select(user => user.Name)
  .Distinct();

Telerik Code Converter converts this to:

Private names = Client.[Select](Function(user) user.Name).Distinct()

2) If I understand you right, you want to have an array containing the ids? You should extend your query to:

Dim A = from b in Client 
        where b.id>0 
        select b.id

Upvotes: 1

Related Questions