I occasionally have a need for an indexed dictionary. Here is my solution:
Code:
Public Class IndexedDictionary(Of TKey, TValue)
#Region "Properties"
Private pCount As Integer
<System.ComponentModel.Description("Gets the number of total pairs.")> _
Public ReadOnly Property Count() As Integer
Get
Return pCount
End Get
End Property
Private itms As List(Of KeyValuePair(Of TKey, TValue))
<System.ComponentModel.Description("Gets the pairs.")> _
Public ReadOnly Property Items() As List(Of KeyValuePair(Of TKey, TValue))
Get
Return itms
End Get
End Property
Private key As List(Of TKey)
Private ReadOnly Property Keys() As List(Of TKey)
Get
Return key
End Get
End Property
Private uniqueKeys As Boolean
<System.ComponentModel.Description("Gets/Sets if the keys in the items are unique.")> _
Public Property KeysAreUnique() As Boolean
Get
Return uniqueKeys
End Get
Set(ByVal value As Boolean)
uniqueKeys = value
End Set
End Property
Private value As List(Of TValue)
Private ReadOnly Property Values() As List(Of TValue)
Get
Return value
End Get
End Property
#End Region
#Region "Methods"
Private Sub ResetCount()
pCount = key.Count
itms.Clear()
For i As Integer = 0 To key.Count - 1
itms.Add(New KeyValuePair(Of TKey, TValue)(key(i), value(i)))
Next
End Sub
Public Sub Add(ByVal pair As KeyValuePair(Of TKey, TValue))
If uniqueKeys AndAlso key.Contains(pair.Key) Then
Throw New ArgumentException("An item with the same key has already been added and the KeysAreUnique property is True.")
Else
key.Add(pair.Key)
value.Add(pair.Value)
Me.ResetCount()
End If
End Sub
Public Sub AddRange(ByVal pairs() As KeyValuePair(Of TKey, TValue))
If uniqueKeys Then
For Each pair As KeyValuePair(Of TKey, TValue) In pairs
If key.Contains(pair.Key) Then
Throw New ArgumentException("An item with the same key has already been added and the KeysAreUnique property is True.")
Else
key.Add(pair.Key)
value.Add(pair.Value)
End If
Next
Me.ResetCount()
Else
For Each pair As KeyValuePair(Of TKey, TValue) In pairs
key.Add(pair.Key)
value.Add(pair.Value)
Next
Me.ResetCount()
End If
End Sub
Public Function GetItem(ByVal i As Integer) As KeyValuePair(Of TKey, TValue)
Return itms.Item(i)
End Function
Public Sub Remove(ByVal key As TKey)
If uniqueKeys Then
Me.key.Remove(key)
Else
For i As Integer = Me.key.Count - 1 To 0 Step -1
If Me.key(i).ToString = key.ToString Then
Me.key.RemoveAt(i)
End If
Next
End If
End Sub
Public Sub Remove(ByVal pair As KeyValuePair(Of TKey, TValue))
If uniqueKeys Then
Me.key.Remove(pair.Key)
Me.value.Remove(pair.Value)
Else
For i As Integer = Me.key.Count - 1 To 0 Step -1
If Me.key(i).ToString = pair.Key.ToString Then
Me.key.RemoveAt(i)
Me.value.RemoveAt(i)
End If
Next
End If
Me.ResetCount()
End Sub
Public Sub RemoveAt(ByVal i As Integer)
Me.key.RemoveAt(i)
Me.value.RemoveAt(i)
Me.ResetCount()
End Sub
#End Region
#Region "New Constructor"
Public Sub New()
itms = New List(Of KeyValuePair(Of TKey, TValue))
key = New List(Of TKey)
uniqueKeys = True
value = New List(Of TValue)
Me.ResetCount()
End Sub
#End Region
End Class