Lance
Lance

Reputation: 611

Fast find an item in a List(of T) by aggregate property

I have a list of objects that looks like this:

Public Class LineItem
    Public Property Name As String
    Public Property Weight As Int32
    Public Property Expression As String
End Class

Private _lineItems As New List(Of LineItem)

I randomly select one item as so:

Public Function SelectItem(ByVal name As String) As LineItem
    Dim items As List(Of LineItem) = CType(Rules.Where(Function(li As LineItem) li.Name = name.Remove("[", "]")).ToList, List(Of LineItem))
    Dim totalWeight As Int32 = items.Sum(Function(li As LineItem) li.Weight)

    If totalWeight > 0 Then
        Dim sum As Int32 = 0
        Dim index As Int32 = (BaseGrammar.Random.Next Mod totalWeight) + 1
        For Each item As LineItem In items
            sum += CInt(item.Weight)
            If sum >= index Then
                Return item
            End If
        Next
    End If
    Return Nothing
End Function

While this works fine for small lists, when the lists get large, obviously it is terribly inefficient. Is there a structure or method that I'm missing that could make this more efficient?

Upvotes: 0

Views: 100

Answers (1)

Nick
Nick

Reputation: 250

I think you function is fine, but did you considered that you code goes through the loop 3 times .. first to take out characters, than find sum, and then capture the subset of items. Maybe if you redo your code by removing initial Linq, you can make a regular loop in which you can fix Name property and sum up Weight. That will cut your time by 33%

Upvotes: 1

Related Questions