从列表中获取子列表,并使用 linq 构建平均值
get sublist from list, and build average, with linq
可能某处有过去的解决方案,我搜索过但没有找到。
我的问题很简单:
学生获得选票。
我在列表上记录选票
然后我想得到一个带有平均值的列表。
仅在 linq 的一条指令中。
例如:3 名学生 Tim、Nick 和 Mark。
在这一年中,他们获得选票:
蒂姆,6 岁,7 岁,8 岁
尼克 8
标记 4,5
使用 linq 我想要一个包含以下内容的列表:
蒂姆 7
尼克 8
标记 4.5
这里是代码
Sub Main
Dim StudentsVotes As List(of Votes) From {New Votes() With {.Name = "Tim", .Vote = 6}, _
New Votes() With {.Name = "Nick", .Vote = 8}, _
New Votes() With {.Name = "Mark", .Vote = 4}, _
New Votes() With {.Name = "Tim", .Vote = 7}, _
New Votes() With {.Name = "Mark", .Vote = 5}, _
New Votes() With {.Name = "Tim", .Vote = 8}}
Dim StudentsAverage As List(Of Votes) = StudentsVotes....() 'Don't know if use .Foreach, Select, Where...
' Here the normal function that i can use, but i would like to use a brief Linq instruction
Private Function getStudentsAverage(ByVal sv As List(of Votes)) As List(Of Votes)
getStudentsAverage = New List(Of Votes)
Dim Votes As List(Of Integer)
For Each studVote As Votes In sv
Dim i As Integer = getStudentsAverage.FindIndex(Function(x) x.Name = studVote.Name)
If i = -1 Then
getStudentsAverage.Add(New Votes() With {.Name = studVote.Name, .Vote = studVote.Vote})
Votes.Add(1)
Else
getStudentsAverage.Item(i).Vote += studVote.Vote
Votes.Item(i) += 1
End If
Next studVote
For a = 0 To getStudentsAverage.Item.Count-1
getStudentsAverage.Item(a).Vote = getStudentsAverage.Item(a).Vote / Votes.Item(a)
Next studAvg
Return getStudentsAverage
End Function
End Sub
Public Class Votes
Public Name As String
Private _Vote As Double
Public Property Vote As Double
Get
Return _Vote
End Get
Set(ByVal value As Double)
_Vote = Math.Round(Value, 2)
End Set
End Property
End Class
好的,感谢JQSOFT,帮助了大家
这里是解决方案:
Dim StudentsAverage As List(Of Votes) = StudentsVotes.GroupBy(Function(x) x.Name).Select(Function(x) New Votes With {.Name = x.Key, .Vote = x.Select(Function(y) y.Vote).Average}).ToList
我在你的 class 中添加了一个构造函数来简化代码。
Public Class Votes
Public Property Name As String
Private _Vote As Double
Public Property Vote As Double
Get
Return _Vote
End Get
Set(ByVal value As Double)
_Vote = Math.Round(value, 2)
End Set
End Property
Public Sub New(n As String, v As Double)
Name = n
Vote = v
End Sub
End Class
我创建了一个新列表来保存平均值。
Private StudentsVotes As New List(Of Votes) From {New Votes("Tim", 6),
New Votes("Nick", 8),
New Votes("Mark", 4),
New Votes("Tim", 7),
New Votes("Mark", 5),
New Votes("Tim", 8)}
Dim VoteAverages As New List(Of Votes)
我使用了 Linq 中的组和匿名类型。
Private Sub OPCode()
Dim Result = (From v As Votes In StudentsVotes
Group v By v.Name
Into StudentAverage = Group
Select New With {.Name = Name, .Average = StudentAverage.Average(Function(v) v.Vote)}).ToList
For Each a In Result
Debug.Print($"{a.Name} {a.Average}")
VoteAverages.Add(New Votes(a.Name, a.Average))
Next
End Sub
可能某处有过去的解决方案,我搜索过但没有找到。 我的问题很简单: 学生获得选票。 我在列表上记录选票 然后我想得到一个带有平均值的列表。 仅在 linq 的一条指令中。
例如:3 名学生 Tim、Nick 和 Mark。 在这一年中,他们获得选票: 蒂姆,6 岁,7 岁,8 岁 尼克 8 标记 4,5
使用 linq 我想要一个包含以下内容的列表: 蒂姆 7 尼克 8 标记 4.5
这里是代码
Sub Main
Dim StudentsVotes As List(of Votes) From {New Votes() With {.Name = "Tim", .Vote = 6}, _
New Votes() With {.Name = "Nick", .Vote = 8}, _
New Votes() With {.Name = "Mark", .Vote = 4}, _
New Votes() With {.Name = "Tim", .Vote = 7}, _
New Votes() With {.Name = "Mark", .Vote = 5}, _
New Votes() With {.Name = "Tim", .Vote = 8}}
Dim StudentsAverage As List(Of Votes) = StudentsVotes....() 'Don't know if use .Foreach, Select, Where...
' Here the normal function that i can use, but i would like to use a brief Linq instruction
Private Function getStudentsAverage(ByVal sv As List(of Votes)) As List(Of Votes)
getStudentsAverage = New List(Of Votes)
Dim Votes As List(Of Integer)
For Each studVote As Votes In sv
Dim i As Integer = getStudentsAverage.FindIndex(Function(x) x.Name = studVote.Name)
If i = -1 Then
getStudentsAverage.Add(New Votes() With {.Name = studVote.Name, .Vote = studVote.Vote})
Votes.Add(1)
Else
getStudentsAverage.Item(i).Vote += studVote.Vote
Votes.Item(i) += 1
End If
Next studVote
For a = 0 To getStudentsAverage.Item.Count-1
getStudentsAverage.Item(a).Vote = getStudentsAverage.Item(a).Vote / Votes.Item(a)
Next studAvg
Return getStudentsAverage
End Function
End Sub
Public Class Votes
Public Name As String
Private _Vote As Double
Public Property Vote As Double
Get
Return _Vote
End Get
Set(ByVal value As Double)
_Vote = Math.Round(Value, 2)
End Set
End Property
End Class
好的,感谢JQSOFT,帮助了大家
这里是解决方案:
Dim StudentsAverage As List(Of Votes) = StudentsVotes.GroupBy(Function(x) x.Name).Select(Function(x) New Votes With {.Name = x.Key, .Vote = x.Select(Function(y) y.Vote).Average}).ToList
我在你的 class 中添加了一个构造函数来简化代码。
Public Class Votes
Public Property Name As String
Private _Vote As Double
Public Property Vote As Double
Get
Return _Vote
End Get
Set(ByVal value As Double)
_Vote = Math.Round(value, 2)
End Set
End Property
Public Sub New(n As String, v As Double)
Name = n
Vote = v
End Sub
End Class
我创建了一个新列表来保存平均值。
Private StudentsVotes As New List(Of Votes) From {New Votes("Tim", 6),
New Votes("Nick", 8),
New Votes("Mark", 4),
New Votes("Tim", 7),
New Votes("Mark", 5),
New Votes("Tim", 8)}
Dim VoteAverages As New List(Of Votes)
我使用了 Linq 中的组和匿名类型。
Private Sub OPCode()
Dim Result = (From v As Votes In StudentsVotes
Group v By v.Name
Into StudentAverage = Group
Select New With {.Name = Name, .Average = StudentAverage.Average(Function(v) v.Vote)}).ToList
For Each a In Result
Debug.Print($"{a.Name} {a.Average}")
VoteAverages.Add(New Votes(a.Name, a.Average))
Next
End Sub