1 #Region "Microsoft.VisualBasic::603f2180efea2a3c5e5f1a0bad2cc3ff, Microsoft.VisualBasic.Core\Extensions\Collection\Linq\Which.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 Which
35     
36     '         Constructor: (+1 OverloadsSub New
37     '         Function: [True], GetMinIndex, Index, (+2 OverloadsIsFalse, (+2 OverloadsIsGreaterThan
38     '                   (+3 OverloadsIsTrue, Max, Min, Top
39     
40     
41     ' /********************************************************************************/
42
43 #End Region
44
45 Imports System.Runtime.CompilerServices
46 Imports Microsoft.VisualBasic.Language
47 Imports Microsoft.VisualBasic.Language.Default
48 Imports Microsoft.VisualBasic.Linq
49
50 Namespace Linq
51
52     ''' <summary>
53     ''' Where is the Min() or Max() or first TRUE or FALSE ?
54     ''' (这个模块之中的函数返回来的都是集合之中的符合条件的对象元素的index坐标)
55     ''' </summary>
56     Public NotInheritable Class Which
57
58         'Default Public Shared ReadOnly Property Items(booleans As IEnumerable(Of Boolean)) As IEnumerable(Of Integer)
59         '    <MethodImpl(MethodImplOptions.AggressiveInlining)>
60         '    Get
61         '        Return Which.Index(booleans)
62         '    End Get
63         'End Property
64
65         ''' <summary>
66         ''' Returns the collection element its index where the test expression <paramref name="predicate"/> result is TRUE
67         ''' </summary>
68         ''' <typeparam name="T"></typeparam>
69         ''' <param name="source"></param>
70         ''' <param name="predicate"></param>
71         ''' <returns></returns>
72         ''' 
73         <MethodImpl(MethodImplOptions.AggressiveInlining)>
74         Public Shared Function Index(Of T)(source As IEnumerable(Of T), predicate As Func(Of T, Boolean)) As IEnumerable(Of Integer)
75             Return source _
76                 .SeqIterator _
77                 .Where(Function(i) predicate(i.value)) _
78                 .Select(Function(o) o.i)
79         End Function
80
81         Public Shared Function GetMinIndex(values As List(Of Double)) As Integer
82             Dim min As Double = Double.MaxValue
83             Dim minIndex As Integer = 0
84             For i As Integer = 0 To values.Count - 1
85                 If values(i) < min Then
86                     min = values(i)
87                     minIndex = i
88                 End If
89             Next
90
91             Return minIndex
92         End Function
93
94         ''' <summary>
95         ''' 在这里不适用Module类型,要不然会和其他的Max拓展函数产生冲突的。。
96         ''' </summary>
97         Private Sub New()
98         End Sub
99
100         ''' <summary>
101         ''' Determines the location, i.e., index of the (first) minimum or maximum of a numeric (or logical) vector.
102         ''' </summary>
103         ''' <typeparam name="T"></typeparam>
104         ''' <param name="x">
105         ''' numeric (logical, integer or double) vector or an R object for which the internal coercion to 
106         ''' double works whose min or max is searched for.
107         ''' </param>
108         ''' <returns></returns>
109         ''' 
110         <MethodImpl(MethodImplOptions.AggressiveInlining)>
111         Public Shared Function Max(Of T As IComparable)(x As IEnumerable(Of T)) As Integer
112             Return x.MaxIndex
113         End Function
114
115         ''' <summary>
116         ''' Determines the location, i.e., index of the (first) minimum or maximum of a numeric (or logical) vector.
117         ''' </summary>
118         ''' <typeparam name="T"></typeparam>
119         ''' <param name="x">
120         ''' numeric (logical, integer or double) vector or an R object for which the internal coercion to 
121         ''' double works whose min or max is searched for.
122         ''' </param>
123         ''' <returns></returns>
124         ''' 
125         <MethodImpl(MethodImplOptions.AggressiveInlining)>
126         Public Shared Function Min(Of T As IComparable)(x As IEnumerable(Of T)) As Integer
127             Return x.MinIndex
128         End Function
129
130         ''' <summary>
131         ''' Return all of the indices which is True
132         ''' </summary>
133         ''' <param name="v"></param>
134         ''' <returns></returns>
135         ''' 
136         <MethodImpl(MethodImplOptions.AggressiveInlining)>
137         Public Shared Function IsTrue(v As IEnumerable(Of Boolean)) As Integer()
138             Return v _
139                 .SeqIterator _
140                 .Where(Function(b) True = +b) _
141                 .Select(Function(i) CInt(i)) _
142                 .ToArray
143         End Function
144
145         ''' <summary>
146         ''' Syntax helper for <see cref="VectorShadows(Of T)(IEnumerable(Of T))"/>
147         ''' </summary>
148         ''' <param name="list"></param>
149         ''' <returns></returns>
150         ''' 
151         <MethodImpl(MethodImplOptions.AggressiveInlining)>
152         Public Shared Function IsTrue(list As ObjectAs Integer()
153             Return IsTrue(DirectCast(list, IEnumerable).Cast(Of Object).Select(Function(o) CBool(o)))
154         End Function
155
156         ''' <summary>
157         ''' Returns all of the indices which is False
158         ''' </summary>
159         ''' <param name="v"></param>
160         ''' <returns></returns>
161         ''' 
162         <MethodImpl(MethodImplOptions.AggressiveInlining)>
163         Public Shared Function IsFalse(v As IEnumerable(Of Boolean)) As Integer()
164             Return v _
165                 .SeqIterator _
166                 .Where(Function(b) False = +b) _
167                 .Select(Function(i) CInt(i)) _
168                 .ToArray
169         End Function
170
171         <MethodImpl(MethodImplOptions.AggressiveInlining)>
172         Public Shared Function IsTrue([operator] As Func(Of Boolean())) As Integer()
173             Return IsTrue([operator]())
174         End Function
175
176         <MethodImpl(MethodImplOptions.AggressiveInlining)>
177         Public Shared Function IsFalse([operator] As Func(Of Boolean())) As Integer()
178             Return Which.IsFalse([operator]())
179         End Function
180
181         Public Shared Function Top(Of T As IComparable(Of T))(seq As IEnumerable(Of T), n As IntegerAs Integer()
182             Return seq.SeqIterator _
183                 .OrderByDescending(Function(x) x.value) _
184                 .Take(n) _
185                 .Ordinals _
186                 .ToArray
187         End Function
188
189         ''' <summary>
190         ''' 查找出列表之中符合条件的所有的索引编号
191         ''' </summary>
192         ''' <typeparam name="T"></typeparam>
193         ''' <param name="array"></param>
194         ''' <param name="condi"></param>
195         ''' <returns></returns>
196         Public Shared Iterator Function [True](Of T)(array As IEnumerable(Of T), condi As Assert(Of T)) As IEnumerable(Of Integer)
197             Dim i%
198
199             For Each x As T In array
200                 If True = condi(x) Then
201                     Yield i
202                 End If
203
204                 i += 1
205             Next
206         End Function
207
208         ''' <summary>
209         ''' 枚举出所有大于目标的顶点编号
210         ''' </summary>
211         ''' <typeparam name="T"></typeparam>
212         ''' <param name="source"></param>
213         ''' <param name="compareTo"></param>
214         ''' <returns></returns>
215         ''' <remarks>因为这个返回的是一个迭代器,所以可以和First结合产生FirstGreaterThan表达式</remarks>
216         ''' 
217         <MethodImpl(MethodImplOptions.AggressiveInlining)>
218         Public Shared Function IsGreaterThan(Of T As IComparable)(source As IEnumerable(Of T), compareTo As T) As IEnumerable(Of Integer)
219             Return source _
220                 .SeqIterator _
221                 .Where(Function(o) Language.GreaterThan(o.value, compareTo)) _
222                 .Select(Function(i) i.i) ' 因为返回的是linq表达式,所以这里就不加ToArray了
223         End Function
224
225         <MethodImpl(MethodImplOptions.AggressiveInlining)>
226         Public Shared Function IsGreaterThan(Of T, C As IComparable)(source As IEnumerable(Of T), getValue As Func(Of T, C), compareTo As C) As IEnumerable(Of Integer)
227             Return Which.IsGreaterThan(source.Select(getValue), compareTo)
228         End Function
229     End Class
230 End Namespace