1 #Region "Microsoft.VisualBasic::5b6f63c84f05a1517436f476a4735f98, Microsoft.VisualBasic.Core\ComponentModel\System.Collections.Generic\MapsHelper.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 MapsHelper
35     
36     '         Properties: [Default]
37     
38     '         Constructor: (+1 OverloadsSub New
39     '         FunctionGetEnumerator, GetValue, IEnumerable_GetEnumerator, ToString
40     
41     '     Class NameMapping
42     
43     '         Constructor: (+1 OverloadsSub New
44     '         Sub: Add
45     
46     '     Structure Map
47     
48     '         Properties: Key, Maps
49     
50     '         Constructor: (+1 OverloadsSub New
51     '         FunctionToString
52     '         Interface IMap
53     
54     '             Properties: Key, Maps
55     
56     
57     
58     '     Structure IDMap
59     
60     '         Properties: Key, Maps
61     
62     '         Function: ParseFromTsv, ParseTsvFile, ToString, TSV
63     
64     
65     ' /********************************************************************************/
66
67 #End Region
68
69 Imports System.Runtime.CompilerServices
70 Imports Microsoft.VisualBasic.ComponentModel.Collection.Generic
71 Imports Microsoft.VisualBasic.Language
72 Imports Microsoft.VisualBasic.Language.Default
73 Imports Microsoft.VisualBasic.Serialization.JSON
74 Imports Microsoft.VisualBasic.Text
75
76 Namespace ComponentModel
77
78     ''' <summary>
79     ''' 其实这个对象就是字典查询的一个简化操作而已
80     ''' </summary>
81     ''' <typeparam name="T"></typeparam>
82     Public Class MapsHelper(Of T) : Implements IEnumerable(Of Map(Of String, T))
83
84         Protected ReadOnly __default As T
85         Protected ReadOnly __maps As IDictionary(Of String, T)
86
87         Default Public ReadOnly Property Value(key$) As T
88             <MethodImpl(MethodImplOptions.AggressiveInlining)>
89             Get
90                 Return GetValue(key)
91             End Get
92         End Property
93
94         Public ReadOnly Property [Default] As T
95             Get
96                 Return __default
97             End Get
98         End Property
99
100         Sub New(map As IReadOnlyDictionary(Of String, T), Optional [default] As T = Nothing)
101             __default = [default]
102             __maps = map
103         End Sub
104
105         Public Function GetValue(key As StringAs T
106             If __maps.ContainsKey(key) Then
107                 Return __maps(key)
108             Else
109                 Return __default
110             End If
111         End Function
112
113         <MethodImpl(MethodImplOptions.AggressiveInlining)>
114         Public Overrides Function ToString() As String
115             Return __maps.ToDictionary.GetJson
116         End Function
117
118         Public Iterator Function GetEnumerator() As IEnumerator(Of Map(Of String, T)) Implements IEnumerable(Of Map(Of String, T)).GetEnumerator
119             For Each tuple As KeyValuePair(Of String, T) In __maps
120                 Yield New Map(Of String, T)(tuple.Key, tuple.Value)
121             Next
122         End Function
123
124         Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
125             Yield GetEnumerator()
126         End Function
127     End Class
128
129     Public Class NameMapping : Inherits MapsHelper(Of String)
130
131         Shared ReadOnly emptyMaps As DefaultValue(Of Dictionary(Of StringString)) = New Dictionary(Of StringString)()
132
133         Sub New(Optional dictionary As Dictionary(Of StringString) = Nothing,
134                 Optional default$ = Nothing)
135             Call MyBase.New(dictionary Or emptyMaps, [default])
136         End Sub
137
138         Public Sub Add(key$, map$)
139             Call __maps.Add(key, map)
140         End Sub
141
142         Public Shared Widening Operator CType(table$(,)) As NameMapping
143             Dim dictionary As New Dictionary(Of StringString)
144
145             For Each map In table.RowIterator
146                 Call dictionary.Add(map(0), map(1))
147             Next
148
149             Return New NameMapping(dictionary, "")
150         End Operator
151
152         <MethodImpl(MethodImplOptions.AggressiveInlining)>
153         Public Shared Narrowing Operator CType(maps As NameMapping) As Dictionary(Of StringString)
154             If maps Is Nothing Then
155                 Return Nothing
156             Else
157                 Return New Dictionary(Of StringString)(dictionary:=maps.__maps)
158             End If
159         End Operator
160     End Class
161
162     Public Structure Map(Of T1, V)
163         Implements IMap
164
165         ''' <summary>
166         ''' The map source
167         ''' </summary>
168         ''' <returns></returns>
169         Public Property Key As T1 Implements IMap.Key
170         ''' <summary>
171         ''' The mapped target value.
172         ''' </summary>
173         ''' <returns></returns>
174         Public Property Maps As V Implements IMap.Maps
175
176         Sub New(x As T1, y As V)
177             Key = x
178             Maps = y
179         End Sub
180
181         Public Overrides Function ToString() As String
182             Return $"map[{Key}, {Maps}]"
183         End Function
184
185         ''' <summary>
186         ''' 与<see cref="IKeyValuePairObject(Of TKey, TValue)"/>相比,这个类型更加倾向于特定化的描述两个对象之间的一一对应关系
187         ''' </summary>
188         Public Interface IMap
189             Property Key As T1
190             Property Maps As V
191         End Interface
192
193         <MethodImpl(MethodImplOptions.AggressiveInlining)>
194         Public Shared Narrowing Operator CType(map As Map(Of T1, V)) As (key As T1, mapAs As V)
195             Return (map.Key, map.Maps)
196         End Operator
197
198         ''' <summary>
199         ''' 因为map主要的作用是获取得到key所配对的value结果,所以在这里是转换为<see cref="Maps"/>结果值的
200         ''' </summary>
201         ''' <param name="map"></param>
202         ''' <returns></returns>
203         ''' 
204         <MethodImpl(MethodImplOptions.AggressiveInlining)>
205         Public Shared Narrowing Operator CType(map As Map(Of T1, V)) As V
206             Return map.Maps
207         End Operator
208     End Structure
209
210     ''' <summary>
211     ''' 字符串类型的映射
212     ''' </summary>
213     Public Structure IDMap : Implements Map(Of StringString).IMap
214         Implements INamedValue
215
216         ''' <summary>
217         ''' 
218         ''' </summary>
219         ''' <returns></returns>
220         ''' <remarks>
221         ''' 虽然说这个对象也实现了<see cref="INamedValue"/>接口,但是Key也可能是会出现重复的
222         ''' </remarks>
223         Public Property Key As String Implements Map(Of StringString).IMap.Key, INamedValue.Key
224         Public Property Maps As String Implements Map(Of StringString).IMap.Maps
225
226         ''' <summary>
227         ''' 将这个映射转换为tsv文件之中的一行数据
228         ''' </summary>
229         ''' <returns></returns>
230         ''' 
231         <MethodImpl(MethodImplOptions.AggressiveInlining)>
232         Public Function TSV() As String
233             Return Key & vbTab & Maps
234         End Function
235
236         Public Shared Function ParseFromTsv(line$) As IDMap
237             Dim t = line.Split(ASCII.TAB)
238
239             If t.Length = 0 Then
240                 Return New IDMap
241             ElseIf t.Length = 1 Then
242                 t.Add("")
243             End If
244
245             Return New IDMap With {
246                 .Key = t(0),
247                 .Maps = t(1)
248             }
249         End Function
250
251         ''' <summary>
252         ''' 将TSV文件之中的数据行解析为IDMapping结果
253         ''' </summary>
254         ''' <param name="path$"></param>
255         ''' <param name="haveHeader"></param>
256         ''' <param name="header"></param>
257         ''' <returns></returns>
258         Public Shared Function ParseTsvFile(path$, Optional haveHeader As Boolean = FalseOptional ByRef header As IDMap = NothingAs IDMap()
259             Dim lines$() = path.ReadAllLines
260             Dim out As New List(Of IDMap)
261
262             If haveHeader Then
263                 header = ParseFromTsv(lines(Scan0))
264             End If
265
266             For Each line As String In lines.Skip(If(haveHeader, 1, 0))
267                 out += IDMap.ParseFromTsv(line)
268             Next
269
270             Return out
271         End Function
272
273         Public Overrides Function ToString() As String
274             Return $"{Key} --> {Maps}"
275         End Function
276
277         <MethodImpl(MethodImplOptions.AggressiveInlining)>
278         Public Shared Widening Operator CType(map As Map(Of StringString)) As IDMap
279             Return New IDMap With {
280                 .Key = map.Key,
281                 .Maps = map.Maps
282             }
283         End Operator
284
285         <MethodImpl(MethodImplOptions.AggressiveInlining)>
286         Public Shared Widening Operator CType(map As IDMap) As Map(Of StringString)
287             Return New Map(Of StringStringWith {
288                 .Key = map.Key,
289                 .Maps = map.Maps
290             }
291         End Operator
292     End Structure
293 End Namespace