Created
February 11, 2012 07:09
-
-
Save digiguru/1797400 to your computer and use it in GitHub Desktop.
To convert any list into a complicated nest of dictionaries for ultra fast lookup.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ExtensionAttribute()> | |
Public Function ToMultiKeyDictionary(Of TSource, TSecKey)(ByVal source As IEnumerable(Of TSource), ByVal ParamArray func() As Func(Of TSource, TSecKey)) As IDictionary | |
'EXAMPLE USAGE | |
'dict = students.ToMultiKeyDictionary( | |
' { | |
' Function(x) x.Age, | |
' Function(x) x.Location, | |
' Function(x) x.Job, | |
' Function(x) x.Name, | |
' Function(x) x}) | |
Dim reverseCollection As New Dictionary(Of Integer, Type) | |
Dim functionsCount As Integer = func.Count | |
Dim dictTypeCollection As New List(Of IDictionary) | |
Dim instanceOfCurrentDictionaryArgument As New Object | |
Dim dictionaryArgQueue As Object = Nothing | |
Dim dictionaryTypes As New List(Of Type) | |
For i = 0 To functionsCount - 1 | |
reverseCollection.Add(i, source.Select(func(func.Count() - (i + 1))).FirstOrDefault().GetType()) | |
Next | |
Dim typeOfGenericDictionary As Type | |
Dim dictionaryTypeArgs() As Type | |
Dim newConstructedType As Type | |
Dim currentDictionaryInstance As IDictionary | |
For i = 0 To reverseCollection.Count - 1 | |
If reverseCollection(i) IsNot GetType(String) Then | |
instanceOfCurrentDictionaryArgument = Activator.CreateInstance(reverseCollection(i)) | |
Else | |
instanceOfCurrentDictionaryArgument = String.Empty | |
End If | |
If instanceOfCurrentDictionaryArgument IsNot Nothing AndAlso dictionaryArgQueue IsNot Nothing Then | |
typeOfGenericDictionary = GetType(Dictionary(Of ,)) | |
dictionaryTypeArgs = {instanceOfCurrentDictionaryArgument.GetType(), dictionaryArgQueue.GetType()} | |
newConstructedType = typeOfGenericDictionary.MakeGenericType(dictionaryTypeArgs) | |
currentDictionaryInstance = Activator.CreateInstance(newConstructedType) | |
dictionaryTypes.Add(newConstructedType) | |
dictionaryArgQueue = currentDictionaryInstance | |
Else | |
dictionaryArgQueue = instanceOfCurrentDictionaryArgument | |
End If | |
Next | |
Dim dict As IDictionary = Activator.CreateInstance(dictionaryTypes.Last()) | |
'If dict IsNot Nothing Then | |
Dim queueObj As Object | |
For Each item In source | |
Dim currentItem = item | |
Dim newObject1 = Activator.CreateInstance(dict.GetType) | |
Dim iterDict As IDictionary = dict | |
Dim itemAddedFlag As Boolean = False | |
Dim currentItemInCollection As IEnumerable(Of TSource) | |
For i = 0 To func.Count - 1 | |
currentItemInCollection = source.Where(Function(x) x.Equals(currentItem)) | |
Dim currentKey As TSecKey = currentItemInCollection.Select(func(i)).FirstOrDefault() | |
If iterDict.Contains(currentKey) AndAlso iterDict(currentKey) IsNot Nothing Then | |
iterDict = iterDict(currentKey) | |
Else | |
queueObj = Nothing | |
For k = 0 To reverseCollection.Count - 1 | |
If queueObj Is Nothing Then | |
queueObj = currentItemInCollection.Select(func(functionsCount - (k + 1))).FirstOrDefault() | |
Else | |
Dim curObject As Object = currentItemInCollection.Select(func(functionsCount - (k + 1))).FirstOrDefault() | |
Dim currentDictionaryFromReverse As IDictionary = Activator.CreateInstance(dictionaryTypes(k - 1)) | |
If iterDict.GetType() = currentDictionaryFromReverse.GetType() Then | |
iterDict.Add(curObject, queueObj) | |
itemAddedFlag = True | |
Exit For | |
End If | |
currentDictionaryFromReverse.Add(curObject, queueObj) | |
queueObj = currentDictionaryFromReverse | |
End If | |
Next | |
If itemAddedFlag Then | |
Exit For | |
End If | |
End If | |
Next | |
Next | |
Return dict | |
End Function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment