1 #Region "Microsoft.VisualBasic::52ec399d0193b08b140bd319a1c3d6c9, Microsoft.VisualBasic.Core\Language\Linq\List(Of T).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 List
35     
36     '         Properties: First, Last
37     
38     '         Constructor: (+5 OverloadsSub New
39     '         Function: [Default], Pop, PopAll, ReverseIterator, ValuesEnumerator
40     '         Operators: (+5 Overloads) -, *, ^, (+6 Overloads) +, (+2 Overloads) <
41     '                    (+2 Overloads) <>, (+2 Overloads) =, (+2 Overloads) >, >>
42     
43     
44     ' /********************************************************************************/
45
46 #End Region
47
48 Imports System.Runtime.CompilerServices
49 Imports Microsoft.VisualBasic.ApplicationServices
50 Imports Microsoft.VisualBasic.ComponentModel
51 Imports Microsoft.VisualBasic.ComponentModel.Ranges.Model
52 Imports Microsoft.VisualBasic.Language.Default
53 Imports Microsoft.VisualBasic.Language.UnixBash.FileSystem
54 Imports Microsoft.VisualBasic.Linq
55 Imports Microsoft.VisualBasic.Scripting.Expressions
56
57 Namespace Language
58
59     ''' <summary>
60     ''' Represents a strongly typed list of objects that can be accessed by index. Provides
61     ''' methods to search, sort, and manipulate lists.To browse the .NET Framework source
62     ''' code for this type, see the Reference Source.
63     ''' (加强版的<see cref="System.Collections.Generic.List(Of T)"/>)
64     ''' </summary>
65     ''' <typeparam name="T">The type of elements in the list.</typeparam>
66     Public Class List(Of T) : Inherits Generic.List(Of T)
67
68 #Region "Improvements Index"
69
70         ''' <summary>
71         ''' The last elements in the collection <see cref="List(Of T)"/>
72         ''' </summary>
73         ''' <returns></returns>
74         Public Property Last As T
75             Get
76                 If Count = 0 Then
77                     Return Nothing
78                 Else
79                     Return MyBase.Item(Count - 1)
80                 End If
81             End Get
82             Set(value As T)
83                 If Count = 0 Then
84                     Call Add(value)
85                 Else
86                     MyBase.Item(Count - 1) = value
87                 End If
88             End Set
89         End Property
90
91         ''' <summary>
92         ''' The first elements in the collection <see cref="List(Of T)"/>
93         ''' </summary>
94         ''' <returns></returns>
95         Public Property First As T
96             Get
97                 If Count = 0 Then
98                     Return Nothing
99                 Else
100                     Return MyBase.Item(0)
101                 End If
102             End Get
103             Set(value As T)
104                 If Count = 0 Then
105                     Call Add(value)
106                 Else
107                     MyBase.Item(Scan0) = value
108                 End If
109             End Set
110         End Property
111
112         ''' <summary>
113         ''' 
114         ''' </summary>
115         ''' <param name="args">同时支持boolean和integer</param>
116         ''' <returns></returns>
117         Default Public Overloads Property Item(args As ObjectAs List(Of T)
118             Get
119                 Dim index = Indexer.Indexing(args)
120                 Return Me(index)
121             End Get
122             Set
123                 Dim index = Indexer.Indexing(args)
124                 Me(index) = Value
125             End Set
126         End Property
127
128         ''' <summary>
129         ''' This indexer property is using for the ODEs-system computing.
130         ''' (这个是为了ODEs计算模块所准备的一个数据接口)
131         ''' </summary>
132         ''' <param name="address"></param>
133         ''' <returns></returns>
134         Default Public Overloads Property Item(address As IAddress(Of Integer)) As T
135             <MethodImpl(MethodImplOptions.AggressiveInlining)>
136             Get
137                 Return Item(address.Address)
138             End Get
139             Set(value As T)
140                 Item(address.Address) = value
141             End Set
142         End Property
143
144         ''' <summary>
145         ''' Can accept negative number as the index value, negative value means ``<see cref="Count"/> - n``, 
146         ''' example as ``list(-1)``: means the last element in this list: ``list(list.Count -1)``
147         ''' </summary>
148         ''' <param name="index%"></param>
149         ''' <returns></returns>
150         Default Public Overloads Property Item(index%) As T
151             Get
152                 If index < 0 Then
153                     index = Count + index  ' -1 -> count -1
154                 End If
155                 Return MyBase.Item(index)
156             End Get
157             Set(value As T)
158                 If index < 0 Then
159                     index = Count + index  ' -1 -> count -1
160                 End If
161                 MyBase.Item(index) = value
162             End Set
163         End Property
164
165         ''' <summary>
166         ''' Using a index vector expression to select/update many elements from this list collection.
167         ''' </summary>
168         ''' <param name="exp$">
169         ''' + ``1``, index=1
170         ''' + ``1:8``, index=1, count=8
171         ''' + ``1->8``, index from 1 to 8
172         ''' + ``8->1``, index from 8 to 1
173         ''' + ``1,2,3,4``, index=1 or  2 or 3 or 4
174         ''' </param>
175         ''' <returns></returns>
176         Default Public Overloads Property Item(exp$) As List(Of T)
177             Get
178                 Dim list As New List(Of T)
179
180                 For Each i% In exp.TranslateIndex
181                     list += Item(index:=i)
182                 Next
183
184                 Return list
185             End Get
186             Set(value As List(Of T))
187                 For Each i As SeqValue(Of IntegerIn exp.TranslateIndex.SeqIterator
188                     Item(index:=+i) = value(i.i)
189                 Next
190             End Set
191         End Property
192
193         Default Public Overloads Property Item(range As IntRange) As List(Of T)
194             <MethodImpl(MethodImplOptions.AggressiveInlining)>
195             Get
196                 Return New List(Of T)(Me.Skip(range.Min).Take(range.Length))
197             End Get
198             Set(value As List(Of T))
199                 Dim indices As Integer() = range.ToArray
200
201                 For i As Integer = 0 To indices.Length - 1
202                     Item(index:=indices(i)) = value(i)
203                 Next
204             End Set
205         End Property
206
207         Default Public Overloads Property Item(indices As IEnumerable(Of Integer)) As List(Of T)
208             <MethodImpl(MethodImplOptions.AggressiveInlining)>
209             Get
210                 Return New List(Of T)(indices.Select(Function(i) Item(index:=i)))
211             End Get
212             Set(value As List(Of T))
213                 For Each i As SeqValue(Of IntegerIn indices.SeqIterator
214                     Item(index:=+i) = value(i.i)
215                 Next
216             End Set
217         End Property
218
219         ''' <summary>
220         ''' Select all of the elements from this list collection is any of them match the condition expression: <paramref name="where"/>
221         ''' </summary>
222         ''' <param name="[where]"></param>
223         ''' <returns></returns>
224         Default Public Overloads ReadOnly Property Item([where] As Predicate(Of T)) As T()
225             <MethodImpl(MethodImplOptions.AggressiveInlining)>
226             Get
227                 Return MyBase.Where(Function(o) where(o)).ToArray
228             End Get
229         End Property
230
231         Default Public Overloads Property Item(booleans As IEnumerable(Of Boolean)) As T()
232             <MethodImpl(MethodImplOptions.AggressiveInlining)>
233             Get
234                 Return Me(Which.IsTrue(booleans))
235             End Get
236             Set(value As T())
237                 For Each i In booleans.SeqIterator
238                     If i.value Then
239                         MyBase.Item(i) = value(i)
240                     End If
241                 Next
242             End Set
243         End Property
244 #End Region
245
246         ''' <summary>
247         ''' Initializes a new instance of the <see cref="List(Of T)"/> class that
248         ''' contains elements copied from the specified collection and has sufficient capacity
249         ''' to accommodate the number of elements copied.
250         ''' (这是一个安全的构造函数,假若输入的参数为空值,则只会创建一个空的列表,而不会抛出错误)
251         ''' </summary>
252         ''' <param name="source">The collection whose elements are copied to the new list.</param>
253         Sub New(source As IEnumerable(Of T))
254             Call MyBase.New(If(source Is Nothing, {}, source.ToArray))
255         End Sub
256
257         ''' <summary>
258         ''' Initializes a new instance of the <see cref="List(Of T)"/> class that
259         ''' contains elements copied from the specified collection and has sufficient capacity
260         ''' to accommodate the number of elements copied.
261         ''' </summary>
262         ''' <param name="x">The collection whose elements are copied to the new list.</param>
263         Sub New(ParamArray x As T())
264             Call MyBase.New(x)
265         End Sub
266
267         ''' <summary>
268         ''' Initializes a new instance of the Microsoft VisualBasic language <see cref="List(Of T)"/> class 
269         ''' that is empty and has the default initial capacity.
270         ''' </summary>
271         Public Sub New()
272             Call MyBase.New
273         End Sub
274
275         ''' <summary>
276         ''' Initializes a new instance of the <see cref="List(Of T)"/> class that
277         ''' is empty and has the specified initial capacity.
278         ''' </summary>
279         ''' <param name="capacity">The number of elements that the new list can initially store.</param>
280         Public Sub New(capacity As Integer)
281             Call MyBase.New(capacity)
282         End Sub
283
284         Public Sub New(size As Integer, fill As T)
285             For i As Integer = 0 To size - 1
286                 Call Add(fill)
287             Next
288         End Sub
289
290         ' 这个Add方法会导致一些隐式转换的类型匹配失败,所以删除掉这个方法
291         'Public Overloads Sub Add(data As IEnumerable(Of T))
292         '    Call MyBase.AddRange(data.SafeQuery)
293         'End Sub
294
295         ''' <summary>
296         ''' Pop all of the elements value in to array from the list object 
297         ''' and then clear all of the <see cref="List(Of T)"/> data.
298         ''' </summary>
299         ''' <returns></returns>
300         Public Function PopAll() As T()
301             Dim array As T() = ToArray()
302             Call Clear()
303             Return array
304         End Function
305
306         ''' <summary>
307         ''' Adds an object to the end of the <see cref="List(Of T)"/>.
308         ''' </summary>
309         ''' <param name="list"></param>
310         ''' <param name="x">
311         ''' The object to be added to the end of the <see cref="List(Of T)"/>. 
312         ''' The value can be null for reference types.
313         ''' </param>
314         ''' <returns></returns>
315         Public Shared Operator +(list As List(Of T), x As T) As List(Of T)
316             If list Is Nothing Then
317                 Return New List(Of T) From {x}
318             Else
319                 Call list.Add(x)
320                 Return list
321             End If
322         End Operator
323
324         ''' <summary>
325         ''' Adds an object to the begin of the <see cref="List(Of T)"/>.
326         ''' </summary>
327         ''' <param name="list"></param>
328         ''' <param name="x">The object to be added to the end of the <see cref="List(Of T)"/>. The
329         ''' value can be null for reference types.</param>
330         ''' <returns></returns>
331         Public Shared Operator +(x As T, list As List(Of T)) As List(Of T)
332             If list Is Nothing Then
333                 Return New List(Of T) From {x}
334             Else
335                 Call list.Insert(Scan0, x)
336                 Return list
337             End If
338         End Operator
339
340         Public Shared Operator *(list As List(Of T), n%) As List(Of T)
341             Select Case n
342                 Case <= 0
343                     Return New List(Of T)
344                 Case 1
345                     Return New List(Of T)(list)
346                 Case > 1
347                     Dim out As New List(Of T)
348
349                     For i As Integer = 1 To n
350                         out.AddRange(list)
351                     Next
352
353                     Return out
354                 Case Else
355                     Throw New NotImplementedException
356             End Select
357         End Operator
358
359         ''' <summary>
360         ''' Removes the first occurrence of a specific object from the <see cref="List(Of T)"/>.
361         ''' </summary>
362         ''' <param name="list"></param>
363         ''' <param name="x">The object to remove from the <see cref="List(Of T)"/>. The value can
364         ''' be null for reference types.</param>
365         ''' <returns></returns>
366         Public Shared Operator -(list As List(Of T), x As T) As List(Of T)
367             Call list.Remove(x)
368             Return list
369         End Operator
370
371         ''' <summary>
372         ''' Adds the elements of the specified collection to the end of the <see cref="List(Of T)"/>.
373         ''' </summary>
374         ''' <param name="list"></param>
375         ''' <param name="vals"></param>
376         ''' <returns></returns>
377         Public Shared Operator +(list As List(Of T), vals As IEnumerable(Of T)) As List(Of T)
378             If Not vals Is Nothing Then
379                 Call list.AddRange(vals.ToArray)
380             End If
381             Return list
382         End Operator
383
384         ''' <summary>
385         ''' Append <paramref name="list2"/> to the end of <paramref name="list1"/>
386         ''' </summary>
387         ''' <param name="list1"></param>
388         ''' <param name="list2"></param>
389         ''' <returns></returns>
390         Public Shared Operator +(list1 As List(Of T), list2 As List(Of T)) As List(Of T)
391             If Not list2 Is Nothing Then
392                 list1.AddRange(list2.ToArray)
393             End If
394             Return list1
395         End Operator
396
397         ''' <summary>
398         ''' Adds the elements of the specified collection to the end of the <see cref="List(Of T)"/>.
399         ''' </summary>
400         ''' <param name="list"></param>
401         ''' <param name="vals"></param>
402         ''' <returns></returns>
403         Public Shared Operator +(list As List(Of T), vals As IEnumerable(Of IEnumerable(Of T))) As List(Of T)
404             If Not vals Is Nothing Then
405                 Call list.AddRange(vals.IteratesALL)
406             End If
407             Return list
408         End Operator
409
410         ''' <summary>
411         ''' Adds the elements of the specified collection to the end of the <see cref="List(Of T)"/>.
412         ''' (这个操作符并不会修改所输入的两个原始序列的内容)
413         ''' </summary>
414         ''' <param name="vals"></param>
415         ''' <param name="list"></param>
416         ''' <returns></returns>
417         Public Shared Operator +(vals As IEnumerable(Of T), list As List(Of T)) As List(Of T)
418             Dim all As List(Of T) = vals.AsList
419             Call all.AddRange(list)
420             Return all
421         End Operator
422
423         ' 请注意,由于下面的代码是和Csv文件操作模块有冲突的,所以代码在这里被注释掉了
424         'Public Shared Operator +(vals As IEnumerable(Of IEnumerable(Of T)), list As List(Of T)) As List(Of T)
425         '    Call list.AddRange(vals.MatrixAsIterator)
426         '    Return list
427         'End Operator
428
429         ''' <summary>
430         ''' 批量的从目标列表之中移除<paramref name="removes"/>集合之中的对象
431         ''' </summary>
432         ''' <param name="list"></param>
433         ''' <param name="removes"></param>
434         ''' <returns></returns>
435         Public Shared Operator -(list As List(Of T), removes As IEnumerable(Of T)) As List(Of T)
436             If Not removes Is Nothing Then
437                 For Each x As T In removes
438                     Call list.Remove(x)
439                 Next
440             End If
441             Return list
442         End Operator
443
444         Public Overloads Shared Operator -(list As List(Of T), all As Func(Of T, Boolean)) As List(Of T)
445             Call list.RemoveAll(Function(x) all(x))
446             Return list
447         End Operator
448
449         ''' <summary>
450         ''' <see cref="List(Of T).RemoveAt(Integer)"/>
451         ''' </summary>
452         ''' <param name="list"></param>
453         ''' <param name="index"></param>
454         ''' <returns></returns>
455         Public Shared Operator -(list As List(Of T), index%) As List(Of T)
456             Call list.RemoveAt(index)
457             Return list
458         End Operator
459
460         ''' <summary>
461         ''' 从输入的向量数组之中移除掉列表之中的指定元素,然后返回<paramref name="vector"/>的剩余元素
462         ''' </summary>
463         ''' <param name="vector"></param>
464         ''' <param name="list"></param>
465         ''' <returns></returns>
466         Public Shared Operator -(vector As T(), list As List(Of T)) As List(Of T)
467             Return vector.AsList - DirectCast(list, IEnumerable(Of T))
468         End Operator
469
470         ''' <summary>
471         ''' 将这个列表对象隐式转换为向量数组
472         ''' </summary>
473         ''' <param name="list"></param>
474         ''' <returns></returns>
475         ''' 
476         <MethodImpl(MethodImplOptions.AggressiveInlining)>
477         Public Shared Narrowing Operator CType(list As List(Of T)) As T()
478             If list Is Nothing Then
479                 Return {}
480             Else
481                 Return list.ToArray
482             End If
483         End Operator
484
485         ' 因为这个隐式会使得数组被默认转换为本List对象,会导致 + 运算符重载失败,所以在这里将这个隐式转换取消掉
486         'Public Shared Widening Operator CType(array As T()) As List(Of T)
487         '    Return New List(Of T)(array)
488         'End Operator
489
490         ''' <summary>
491         ''' Find a item in the <see cref="List(Of T)"/>
492         ''' </summary>
493         ''' <param name="list"></param>
494         ''' <param name="find"></param>
495         ''' <returns></returns>
496         Public Shared Operator ^(list As List(Of T), find As Func(Of T, Boolean)) As T
497             Dim LQuery = LinqAPI.DefaultFirst(Of T) _
498  _
499                 () <= From x As T
500                       In list.AsParallel
501                       Where True = find(x)
502                       Select x
503
504             Return LQuery
505         End Operator
506
507         ''' <summary>
508         ''' Elements count not equals to a specific number?
509         ''' </summary>
510         ''' <param name="list"></param>
511         ''' <param name="count%"></param>
512         ''' <returns></returns>
513         Public Shared Operator <>(list As List(Of T), count%) As Boolean
514             If list Is Nothing Then
515                 Return True
516             End If
517             Return list.Count <> count
518         End Operator
519
520         ''' <summary>
521         ''' Assert that the element counts of this list object is equals to a specifc number?
522         ''' </summary>
523         ''' <param name="list"></param>
524         ''' <param name="count%"></param>
525         ''' <returns></returns>
526         <MethodImpl(MethodImplOptions.AggressiveInlining)>
527         Public Shared Operator =(list As List(Of T), count%) As Boolean
528             Return Not (list <> count)
529         End Operator
530
531         ''' <summary>
532         ''' <see cref="Enumerable.SequenceEqual(Of T)"/>
533         ''' </summary>
534         ''' <param name="list"></param>
535         ''' <param name="collection"></param>
536         ''' <returns></returns>
537         <MethodImpl(MethodImplOptions.AggressiveInlining)>
538         Public Shared Operator =(list As List(Of T), collection As IEnumerable(Of T)) As Boolean
539             Return list.SequenceEqual(collection)
540         End Operator
541
542         <MethodImpl(MethodImplOptions.AggressiveInlining)>
543         Public Shared Operator <>(list As List(Of T), collection As IEnumerable(Of T)) As Boolean
544             Return Not list.SequenceEqual(collection)
545         End Operator
546
547         ''' <summary>
548         ''' Dump this collection data to the file system.
549         ''' </summary>
550         ''' <param name="source"></param>
551         ''' <param name="path"></param>
552         ''' <returns></returns>
553         <MethodImpl(MethodImplOptions.AggressiveInlining)>
554         Public Shared Operator >(source As List(Of T), path As StringAs Boolean
555             Return IOHandler.DefaultHandle()(source, path, System.Text.Encoding.UTF8)
556         End Operator
557
558         ''' <summary>
559         ''' <see cref="Count"/> of <paramref name="list"/> &gt; <paramref name="n"/>
560         ''' </summary>
561         ''' <param name="list"></param>
562         ''' <param name="n%"></param>
563         ''' <returns></returns>
564         <MethodImpl(MethodImplOptions.AggressiveInlining)>
565         Public Shared Operator >(list As List(Of T), n%) As Boolean
566             Return list.Count > n
567         End Operator
568
569         <MethodImpl(MethodImplOptions.AggressiveInlining)>
570         Public Shared Operator <(list As List(Of T), n%) As Boolean
571             Return Not list > n
572         End Operator
573
574         <MethodImpl(MethodImplOptions.AggressiveInlining)>
575         Public Shared Operator >>(source As List(Of T), path As IntegerAs Boolean
576             Dim file As FileHandle = __getHandle(path)
577             Return source > file.FileName
578         End Operator
579
580         Public Shared Operator <(source As List(Of T), path As StringAs Boolean
581             Throw New NotImplementedException
582         End Operator
583
584         Public Iterator Function ReverseIterator() As IEnumerable(Of T)
585             For i As Integer = Count - 1 To 0 Step -1
586                 Yield MyBase.Item(i)
587             Next
588         End Function
589
590         ''' <summary>
591         ''' Enums all of the elements in this collection list object by return a value reference type
592         ''' </summary>
593         ''' <returns></returns>
594         Public Iterator Function ValuesEnumerator() As IEnumerable(Of Value(Of T))
595             Dim o As New Value(Of T)
596
597             For Each x As T In Me
598                 o.Value = x
599                 Yield o
600             Next
601         End Function
602
603         <MethodImpl(MethodImplOptions.AggressiveInlining)>
604         Public Shared Function [Default]() As DefaultValue(Of List(Of T))
605             Return New List(Of T)
606         End Function
607
608         ''' <summary>
609         ''' Get the <see cref="Last"/> element value and then removes the last element.
610         ''' </summary>
611         ''' <returns></returns>
612         Public Function Pop() As T
613             Dim out = Last
614             Call Me.RemoveLast
615             Return out
616         End Function
617     End Class
618 End Namespace