Wednesday, March 23, 2011

Improve coding with List Intersect using Net 3.5

I've a class that has a list of IDs with a function for adding new IDs from a list of objects.

I've got this resolved, but I'm sure this can be done with much less code.

Public Class Page

  Private _IdList As List(Of Integer)
  Private _HasNewItems As Boolean = False

  Public Sub AddItems(ByVal Items As List(Of Item))

    Dim itemsID = From itemX In Items _
                  Select itemX.ID

    Dim list As List(Of Integer) = itemsID.ToList

    If _IdList.Intersect(list).Count = list.Count Then
      _HasNewItems = False
    Else
      _HasNewItems = True
      _IdList.AddRange(list)
      _IdList = _IdList.Distinct
    End If

  End Sub

End Class

So how can this be done with less code and more from a NET 3.5 perspective...

From stackoverflow
  • Try the following

    Public Sub AddItems(ByVal items as List(Of Item))
      Dim oldCount = _IdList.Count
      _IdList.AddRange(items.Select(Function(x) x.ID).Except(_IdList))
      _HasNewItems = oldCount < _IdList.Count
    End Sub
    

    The trick here is that Except will return all items Except when they are present in the enumerable passed as the argument (In this case _IdList). So items.Except(_IdList) is all new items.

    JaredPar : Missed that, will update answer
  • If your code allows it you could store the ids in a HashSet instead of a List. Then you can just add all the 'new' ids to the HashSet without creating duplicates.

    Edit - added code (sorry c#):

        HashSet<int> idList;
        void AddItems(List<Item> items)
        {
            idList.UnionWith(from item in items select item.Id);
        }
    
  • Just for completeness, heres a VB version of it depends suggestion of using a HashSet:

    Public Class Page
    
      Private _IdList As HashSet(Of Integer)
      Private _HasNewItems As Boolean = False
    
      Public Sub AddItems(ByVal Items As List(Of Item))
    
        Dim itemsID = From itemX In Items _
                      Select itemX.ID
    
        Dim localResult as Boolean
    
        For Each id As Integer In itemsID
         localResult = _IdList.Add(id)         
         _HasNewItems = _HasNewItems OrElse localResult
        Next
      End Sub
    
    End Class
    

0 comments:

Post a Comment