1 #Region "Microsoft.VisualBasic::3eb16803ff94b94d0fb4295fc5b9b574, Microsoft.VisualBasic.Core\ComponentModel\System.Collections.Generic\Dictionary(Of T, V).vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class HashTable
35     
36     '         Constructor: (+1 OverloadsSub New
37     
38     '     Class Dictionary
39     
40     '         Constructor: (+3 OverloadsSub New
41     
42     '         Function: Find, GetValueList, Remove, SafeGetValue, (+2 OverloadsTryGetValue
43     
44     '         Sub: Add, AddRange, InsertOrUpdate
45     
46     '         Operators: (+2 Overloads) -, ^, +, <=, >=
47     
48     
49     ' /********************************************************************************/
50
51 #End Region
52
53 Imports System.Runtime.CompilerServices
54 Imports Microsoft.VisualBasic.ComponentModel.Collection.Generic
55 Imports Microsoft.VisualBasic.Language
56 Imports Microsoft.VisualBasic.Language.Default
57 Imports Microsoft.VisualBasic.Linq
58
59 Namespace ComponentModel.Collection
60
61     Public Class HashTable(Of T) : Inherits Dictionary(Of String, T)
62
63         ReadOnly assert As Assert(Of Object)
64
65         Default Public Overloads Property Item(key As StringAs DefaultValue(Of T)
66             Get
67                 Dim value As T = If(ContainsKey(key), MyBase.Item(key), Nothing)
68                 Return New DefaultValue(Of T)(value, assert)
69             End Get
70             Set(value As DefaultValue(Of T))
71                 MyBase.Item(key) = value.DefaultValue
72             End Set
73         End Property
74
75         Sub New(copy As Dictionary(Of String, T), Optional assert As Assert(Of Object) = Nothing)
76             Call MyBase.New(copy)
77
78             Me.assert = assert
79         End Sub
80     End Class
81
82     ''' <summary>
83     ''' Represents a collection of keys and values.To browse the .NET Framework source
84     ''' code for this type, see the Reference Source.
85     ''' </summary>
86     ''' <typeparam name="V"></typeparam>
87     Public Class Dictionary(Of V As INamedValue) : Inherits SortedDictionary(Of String, V)
88         Implements IEnumerable(Of V)
89
90         Default Public Overloads Property Item(o As V) As V
91             <MethodImpl(MethodImplOptions.AggressiveInlining)>
92             Get
93                 Return MyBase.Item(o.Key)
94             End Get
95             Set(value As V)
96                 MyBase.Item(o.Key) = value
97             End Set
98         End Property
99
100         ''' <summary>
101         ''' 不存在的键名或者空值的键名都会返回``Nothing``
102         ''' </summary>
103         ''' <param name="key"></param>
104         ''' <returns></returns>
105         Default Public Overloads Property Item(key As StringAs V
106             <MethodImpl(MethodImplOptions.AggressiveInlining)>
107             Get
108                 If Not key Is Nothing AndAlso ContainsKey(key) Then
109                     Return MyBase.Item(key)
110                 Else
111                     Return Nothing
112                 End If
113             End Get
114             <MethodImpl(MethodImplOptions.AggressiveInlining)>
115             Set(value As V)
116                 MyBase.Item(key) = value
117             End Set
118         End Property
119
120         ''' <summary>
121         ''' The <paramref name="keys"/> element counts should equals to the value length when invoke property set.
122         ''' </summary>
123         ''' <param name="keys"></param>
124         ''' <returns></returns>
125         Default Public Overloads Property Item(keys As IEnumerable(Of String)) As V()
126             <MethodImpl(MethodImplOptions.AggressiveInlining)>
127             Get
128                 Return keys _
129                     .Select(Function(key) MyBase.Item(key)) _
130                     .ToArray
131             End Get
132             Set(value As V())
133                 For Each key As SeqValue(Of StringIn keys.SeqIterator
134                     MyBase.Item(key.value) = value(key)
135                 Next
136             End Set
137         End Property
138
139         Sub New()
140             Call MyBase.New
141         End Sub
142
143         ''' <summary>
144         ''' Initializes a new instance of the System.Collections.Generic.SortedDictionary`2
145         ''' class that contains elements copied from the specified System.Collections.Generic.IDictionary`2
146         ''' and uses the default System.Collections.Generic.IComparer`1 implementation for
147         ''' the key type.
148         ''' </summary>
149         ''' <param name="source">
150         ''' The System.Collections.Generic.IDictionary`2 whose elements are copied to the
151         ''' new System.Collections.Generic.SortedDictionary`2.
152         ''' </param>
153         Sub New(source As Dictionary(Of String, V))
154             Call MyBase.New(source)
155         End Sub
156
157         Sub New(source As IEnumerable(Of V))
158             Call Me.New
159
160             For Each x As V In source
161                 Call Add(x)
162             Next
163         End Sub
164
165         Public Function GetValueList() As List(Of V)
166             Return Values.AsList
167         End Function
168
169         ''' <summary>
170         ''' Adds an element with the specified key and value into the System.Collections.Generic.SortedDictionary`2.
171         ''' </summary>
172         ''' <param name="item"></param>
173         Public Overloads Sub Add(item As V)
174             Call MyBase.Add(item.Key, item)
175         End Sub
176
177         Public Sub AddRange(source As IEnumerable(Of V))
178             For Each x As V In source
179                 Call MyBase.Add(x.Key, x)
180             Next
181         End Sub
182
183         Public Sub InsertOrUpdate(x As V)
184             If Me.ContainsKey(x.Key) Then
185                 Me(x.Key) = x
186             Else
187                 Call MyBase.Add(x.Key, x)
188             End If
189         End Sub
190
191         ''' <summary>
192         '''
193         ''' </summary>
194         ''' <param name="name">不区分大小写的</param>
195         ''' <returns></returns>
196         Public Function Find(name As StringAs V
197             If MyBase.ContainsKey(name) Then
198                 Return Me(name)
199             Else
200                 Dim key As New Value(Of String)
201
202                 If Me.ContainsKey(key = name.ToLower) Then
203                     Return Me(name)
204                 ElseIf Me.ContainsKey(key = name.ToUpper) Then
205                     Return Me(name)
206                 Else
207                     Return Nothing
208                 End If
209             End If
210         End Function
211
212         ''' <summary>
213         ''' If the value is not found in the hash directionary, then the default value will be returns, and the default value is nothing.
214         ''' </summary>
215         ''' <param name="name"></param>
216         ''' <param name="[default]"></param>
217         ''' <param name="success">可能value本身就是空值,所以在这里使用这个参数来判断是否存在</param>
218         ''' <returns></returns>
219         Public Function SafeGetValue(name As String,
220                                      Optional ByRef [default] As V = Nothing,
221                                      Optional ByRef success As Boolean = FalseAs V
222             Dim x As V = Nothing
223
224             success = MyBase.TryGetValue(name, x)
225
226             If success Then
227                 Return x
228             Else
229                 Return [default]
230             End If
231         End Function
232
233         ''' <summary>
234         ''' Gets the value associated with the specified key.(假若找不到键值,就会返回Nothing)
235         ''' </summary>
236         ''' <param name="name">The key of the value to get.</param>
237         ''' <param name="success">true if the System.Collections.Generic.SortedDictionary`2 contains an element
238         ''' with the specified key; otherwise, false.</param>
239         ''' <returns>When this method returns, the value associated with the specified key, if the
240         ''' key is found; otherwise, the default value for the type of the value parameter.</returns>
241         Public Overloads Function TryGetValue(name As StringOptional ByRef success As Boolean = TrueAs V
242             Dim value As V = Nothing
243             success = MyBase.TryGetValue(name, value)
244             Return value
245         End Function
246
247         Public Overloads Function TryGetValue(name$, [default] As V) As V
248             If MyBase.ContainsKey(name) Then
249                 Return MyBase.Item(name)
250             Else
251                 Return [default]
252             End If
253         End Function
254
255         ''' <summary>
256         ''' 假若目标元素不存在于本字典之中,则会返回False
257         ''' </summary>
258         ''' <param name="x"></param>
259         ''' <returns></returns>
260         Public Overloads Function Remove(x As V) As Boolean
261             If Me.ContainsKey(x.Key) Then
262                 Return Me.Remove(x.Key)
263             Else
264                 Return False
265             End If
266         End Function
267
268         ''' <summary>
269         ''' Adds an element with the specified key and value into the System.Collections.Generic.SortedDictionary`2.
270         ''' </summary>
271         ''' <param name="list"></param>
272         ''' <param name="item"></param>
273         ''' <returns></returns>
274         Public Shared Operator +(list As Dictionary(Of V), item As V) As Dictionary(Of V)
275             Call list.Add(item)
276             Return list
277         End Operator
278
279         ''' <summary>
280         ''' Find a variable in the hash table
281         ''' </summary>
282         ''' <param name="table"></param>
283         ''' <param name="uid"></param>
284         ''' <returns></returns>
285         Public Shared Operator ^(table As Dictionary(Of V), uid As StringAs V
286             If table.ContainsKey(uid) Then
287                 Return table(uid)
288             Else
289                 Return Nothing
290             End If
291         End Operator
292
293         Public Shared Operator -(hash As Dictionary(Of V), id As StringAs Dictionary(Of V)
294             Call hash.Remove(id)
295             Return hash
296         End Operator
297
298         ''' <summary>
299         ''' 批量移除字典之中的键值对
300         ''' </summary>
301         ''' <param name="hash"></param>
302         ''' <param name="keys">需要移除的键名的列表</param>
303         ''' <returns></returns>
304         Public Shared Operator -(hash As Dictionary(Of V), keys As IEnumerable(Of String)) As Dictionary(Of V)
305             For Each k As String In keys
306                 Call hash.Remove(k)
307             Next
308
309             Return hash
310         End Operator
311
312         Public Shared Widening Operator CType(source As System.Collections.Generic.List(Of V)) As Dictionary(Of V)
313             Return source.ToDictionary
314         End Operator
315
316         Public Shared Widening Operator CType(table As Dictionary(Of String, V)) As Dictionary(Of V)
317             Return New Dictionary(Of V)(table)
318         End Operator
319
320         Public Shared Widening Operator CType(source As V()) As Dictionary(Of V)
321             Return source.ToDictionary
322         End Operator
323
324         Public Shared Narrowing Operator CType(source As Dictionary(Of V)) As List(Of V)
325             Return New List(Of V)(source.Values)
326         End Operator
327
328         Public Shared Narrowing Operator CType(table As Dictionary(Of V)) As Dictionary(Of String, V)
329             Return New Dictionary(Of String, V)(table)
330         End Operator
331
332         ''' <summary>
333         ''' Get value by key.
334         ''' </summary>
335         ''' <param name="hash"></param>
336         ''' <param name="key"></param>
337         ''' <returns></returns>
338         Public Shared Operator <=(hash As Dictionary(Of V), key As StringAs V
339             Return hash(key)
340         End Operator
341
342         Public Shared Operator >=(hash As Dictionary(Of V), null As StringAs V
343             Throw New NotSupportedException
344         End Operator
345
346         ''' <summary>
347         ''' <see cref="ContainsKey(String)"/>
348         ''' </summary>
349         ''' <param name="hash"></param>
350         ''' <param name="null"></param>
351         ''' <returns></returns>
352         Public Shared Operator &(hash As Dictionary(Of V), null As StringAs Boolean
353             Return hash.ContainsKey(null)
354         End Operator
355
356         ''' <summary>
357         ''' <see cref="ContainsKey(String)"/>
358         ''' </summary>
359         ''' <param name="table"></param>
360         ''' <param name="x"></param>
361         ''' <returns></returns>
362         Public Shared Operator &(table As Dictionary(Of V), x As V) As Boolean
363             Return table & x.Key
364         End Operator
365
366         Public Shared Narrowing Operator CType(map As Dictionary(Of V)) As V()
367             Return map.Values.ToArray
368         End Operator
369
370         ' 实现这个集合接口会和字典的集合接口出现冲突
371         'Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator(Of V) Implements IEnumerable(Of V).GetEnumerator
372         '    For Each x In MyBase.Values
373         '        Yield x
374         '    Next
375         'End Function
376     End Class
377 End Namespace