【问题标题】:Manipulating List of Structure Array操作结构数组列表
【发布时间】:2017-12-10 05:27:23
【问题描述】:

我有一个结构,例如:

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

现在主要的数组声明是:Dim Client as new list of User

这个新的数组列表包含所有记录。现在如何在不使用循环的情况下执行以下操作,例如:
1)我需要将所有不同的名称填充到组合框中。如果是字符串数组,我可以做到

Combobox1.addrange(tmpstring.distinct.toarray)

但是,因为这是一种类型(例如用户)的结构,该怎么办?

2) 如何使用 linq 仅将一组字段数据填充到数组中。例如如果我在 Client where b.id>0 ' 中执行 Dim A = from b ,则返回所有数组项。如何只获得 id ?

谢谢。

【问题讨论】:

  • tmpstring 是什么?
  • @Greatchap 你需要使用数组吗?如果将其设为具有属性而不是字段的类,则可以使用 List(Of User) 作为 ComboBox 的数据源。
  • 正是...改用一个类
  • 我不能,因为我的应用程序现在可以工作,因为它是一个结构而不是一个类。再加上我在操纵类方面的知识不是很好。
  • @Greatchap 好吧,稍微使用一下就很简单了。它与使用数组并没有什么不同,只是更加灵活。您想看看使用类而不是结构会发生什么变化吗?

标签: .net vb.net linq


【解决方案1】:

1)我对VB不是很熟悉,所以这里是C#中的解决方案:

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

Telerik Code Converter 将其转换为:

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

2) 如果我理解正确,您想要一个包含 id 的数组吗?您应该将查询扩展到:

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

【讨论】:

  • 感谢您的帮助。第 2 点没问题,但第 1 点给出错误。
  • 什么样的错误?我创建了一个小例子,它工作正常。从您最初的帖子来看,您的Structure 的属性似乎是private。当然,他们需要public 才能使用 LINQ 评估它们。
  • 对不起。这是工作。谢谢你。顺便说一句,如果我必须匹配多个值,那么如何做例如dim a = from b in client where id = 1 or id = 2 依此类推,如果值太多并且您不想使用 or。
  • 您可以创建一个 id 数组,然后使用 array.Contains(b.id) 例如。
【解决方案2】:

List(Of Class)(引用类型)比结构(值类型)更灵活。

使用列表(结构):

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"})

要填写 ComboBox 列表,您可以:

'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)

当用户从列表中选择项目时获取项目值:

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

使用列表(类)

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"})

现在您可以使用其.DataSource 属性填充您的 ComboBox

  '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

【讨论】:

  • 谢谢。感谢你的帮助。 :)
猜你喜欢
  • 1970-01-01
  • 2023-03-05
  • 2011-07-13
  • 2014-12-03
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
相关资源
最近更新 更多