1 #Region "Microsoft.VisualBasic::57d2eabef8da6fedfecc9dca7d02e0ef, 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, 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         ''' </summary>
413         ''' <param name="vals"></param>
414         ''' <param name="list"></param>
415         ''' <returns></returns>
416         Public Shared Operator +(vals As IEnumerable(Of T), list As List(Of T)) As List(Of T)
417             Dim all As List(Of T) = vals.AsList
418             Call all.AddRange(list)
419             Return all
420         End Operator
421
422         ' 请注意,由于下面的代码是和Csv文件操作模块有冲突的,所以代码在这里被注释掉了
423         'Public Shared Operator +(vals As IEnumerable(Of IEnumerable(Of T)), list As List(Of T)) As List(Of T)
424         '    Call list.AddRange(vals.MatrixAsIterator)
425         '    Return list
426         'End Operator
427
428         ''' <summary>
429         ''' 批量的从目标列表之中移除<paramref name="removes"/>集合之中的对象
430         ''' </summary>
431         ''' <param name="list"></param>
432         ''' <param name="removes"></param>
433         ''' <returns></returns>
434         Public Shared Operator -(list As List(Of T), removes As IEnumerable(Of T)) As List(Of T)
435             If Not removes Is Nothing Then
436                 For Each x As T In removes
437                     Call list.Remove(x)
438                 Next
439             End If
440             Return list
441         End Operator
442
443         Public Overloads Shared Operator -(list As List(Of T), all As Func(Of T, Boolean)) As List(Of T)
444             Call list.RemoveAll(Function(x) all(x))
445             Return list
446         End Operator
447
448         ''' <summary>
449         ''' <see cref="List(Of T).RemoveAt(Integer)"/>
450         ''' </summary>
451         ''' <param name="list"></param>
452         ''' <param name="index"></param>
453         ''' <returns></returns>
454         Public Shared Operator -(list As List(Of T), index%) As List(Of T)
455             Call list.RemoveAt(index)
456             Return list
457         End Operator
458
459         ''' <summary>
460         ''' 从输入的向量数组之中移除掉列表之中的指定元素,然后返回<paramref name="vector"/>的剩余元素
461         ''' </summary>
462         ''' <param name="vector"></param>
463         ''' <param name="list"></param>
464         ''' <returns></returns>
465         Public Shared Operator -(vector As T(), list As List(Of T)) As List(Of T)
466             Return vector.AsList - DirectCast(list, IEnumerable(Of T))
467         End Operator
468
469         ''' <summary>
470         ''' 将这个列表对象隐式转换为向量数组
471         ''' </summary>
472         ''' <param name="list"></param>
473         ''' <returns></returns>
474         ''' 
475         <MethodImpl(MethodImplOptions.AggressiveInlining)>
476         Public Shared Narrowing Operator CType(list As List(Of T)) As T()
477             If list Is Nothing Then
478                 Return {}
479             Else
480                 Return list.ToArray
481             End If
482         End Operator
483
484         ' 因为这个隐式会使得数组被默认转换为本List对象,会导致 + 运算符重载失败,所以在这里将这个隐式转换取消掉
485         'Public Shared Widening Operator CType(array As T()) As List(Of T)
486         '    Return New List(Of T)(array)
487         'End Operator
488
489         ''' <summary>
490         ''' Find a item in the <see cref="List(Of T)"/>
491         ''' </summary>
492         ''' <param name="list"></param>
493         ''' <param name="find"></param>
494         ''' <returns></returns>
495         Public Shared Operator ^(list As List(Of T), find As Func(Of T, Boolean)) As T
496             Dim LQuery = LinqAPI.DefaultFirst(Of T) _
497  _
498                 () <= From x As T
499                       In list.AsParallel
500                       Where True = find(x)
501                       Select x
502
503             Return LQuery
504         End Operator
505
506         ''' <summary>
507         ''' Elements count not equals to a specific number?
508         ''' </summary>
509         ''' <param name="list"></param>
510         ''' <param name="count%"></param>
511         ''' <returns></returns>
512         Public Shared Operator <>(list As List(Of T), count%) As Boolean
513             If list Is Nothing Then
514                 Return True
515             End If
516             Return list.Count <> count
517         End Operator
518
519         ''' <summary>
520         ''' Assert that the element counts of this list object is equals to a specifc number?
521         ''' </summary>
522         ''' <param name="list"></param>
523         ''' <param name="count%"></param>
524         ''' <returns></returns>
525         <MethodImpl(MethodImplOptions.AggressiveInlining)>
526         Public Shared Operator =(list As List(Of T), count%) As Boolean
527             Return Not (list <> count)
528         End Operator
529
530         ''' <summary>
531         ''' <see cref="Enumerable.SequenceEqual(Of T)"/>
532         ''' </summary>
533         ''' <param name="list"></param>
534         ''' <param name="collection"></param>
535         ''' <returns></returns>
536         <MethodImpl(MethodImplOptions.AggressiveInlining)>
537         Public Shared Operator =(list As List(Of T), collection As IEnumerable(Of T)) As Boolean
538             Return list.SequenceEqual(collection)
539         End Operator
540
541         <MethodImpl(MethodImplOptions.AggressiveInlining)>
542         Public Shared Operator <>(list As List(Of T), collection As IEnumerable(Of T)) As Boolean
543             Return Not list.SequenceEqual(collection)
544         End Operator
545
546         ''' <summary>
547         ''' Dump this collection data to the file system.
548         ''' </summary>
549         ''' <param name="source"></param>
550         ''' <param name="path"></param>
551         ''' <returns></returns>
552         <MethodImpl(MethodImplOptions.AggressiveInlining)>
553         Public Shared Operator >(source As List(Of T), path As StringAs Boolean
554             Return IOHandler.DefaultHandle()(source, path, System.Text.Encoding.UTF8)
555         End Operator
556
557         ''' <summary>
558         ''' <see cref="Count"/> of <paramref name="list"/> &gt; <paramref name="n"/>
559         ''' </summary>
560         ''' <param name="list"></param>
561         ''' <param name="n%"></param>
562         ''' <returns></returns>
563         <MethodImpl(MethodImplOptions.AggressiveInlining)>
564         Public Shared Operator >(list As List(Of T), n%) As Boolean
565             Return list.Count > n
566         End Operator
567
568         <MethodImpl(MethodImplOptions.AggressiveInlining)>
569         Public Shared Operator <(list As List(Of T), n%) As Boolean
570             Return Not list > n
571         End Operator
572
573         <MethodImpl(MethodImplOptions.AggressiveInlining)>
574         Public Shared Operator >>(source As List(Of T), path As IntegerAs Boolean
575             Dim file As FileHandle = __getHandle(path)
576             Return source > file.FileName
577         End Operator
578
579         Public Shared Operator <(source As List(Of T), path As StringAs Boolean
580             Throw New NotImplementedException
581         End Operator
582
583         ''' <summary>
584         ''' Enums all of the elements in this collection list object by return a value reference type
585         ''' </summary>
586         ''' <returns></returns>
587         Public Iterator Function ValuesEnumerator() As IEnumerable(Of Value(Of T))
588             Dim o As New Value(Of T)
589
590             For Each x As T In Me
591                 o.Value = x
592                 Yield o
593             Next
594         End Function
595
596         <MethodImpl(MethodImplOptions.AggressiveInlining)>
597         Public Shared Function [Default]() As DefaultValue(Of List(Of T))
598             Return New List(Of T)
599         End Function
600
601         ''' <summary>
602         ''' Get the <see cref="Last"/> element value and then removes the last element.
603         ''' </summary>
604         ''' <returns></returns>
605         Public Function Pop() As T
606             Dim out = Last
607             Call Me.RemoveLast
608             Return out
609         End Function
610     End Class
611 End Namespace