如何从一个类的集合中投影两个属性来获得两个列表的最大计数



假设我有以下代码:

   Private Sub Calculate()
    Dim basket As New List(Of AppleOrangePair)
    For i = 1 To 10000
        Dim pair As New AppleOrangePair
        If i Mod 10 = 0 Then pair.Orange.IsRotten = True
        basket.Add(pair)
    Next
    Dim stopwatch As New Stopwatch
    stopwatch.Start()
    Dim edibleAppleCount = basket.AsEnumerable.Count(Function(pair) Not pair.Apple.IsRotten)
    Dim edibleOrangeCount = basket.AsEnumerable.Count(Function(pair) Not pair.Orange.IsRotten)
    LargestCount = Math.Max(edibleAppleCount, edibleOrangeCount)
    Time = stopwatch.ElapsedMilliseconds
    stopwatch.Stop()
End Sub
Class Fruit
    Property IsRotten As Boolean
End Class
Class Apple
    Inherits Fruit
End Class
Class Orange
    Inherits Fruit
End Class
Class AppleOrangePair
    Public Sub New()
        Apple = New Apple
        Orange = New Orange
    End Sub
    Public Property Apple As Apple
    Public Property Orange As Orange
End Class

这段代码非常快,但它需要对篮子进行两次迭代。这个代码可以重写吗?这样篮子就只交互一次?

您可以使用Aggregate方法并在其中实现条件Count

Dim edibleCount = basket.Aggregate(New With {.Apple = 0, .Orange = 0}, _
                                   Function(acc, pair) New With {
                                       .Apple = If(pair.Apple.IsRotten, acc.Apple, acc.Apple + 1),
                                       .Orange = If(pair.Orange.IsRotten, acc.Orange, acc.Orange + 1)
                                   })
results.Add(Math.Max(edibleCount.Apple, edibleCount.Orange))

快速性能测试显示,它比您的方法快25%左右。

在我们急于尝试新技术的过程中,我们忽略了久经考验的技术。在我的测试中,一个简单的For循环比任何一个LINQ选项都快30%:

    Dim applecount, orangecount As Long
    For I = 0 To basket.Count - 1
        applecount += Convert.ToInt64(Not basket(I).Apple.IsRotten)
        orangecount += Convert.ToInt64(Not basket(I).Orange.IsRotten)
    Next

最新更新