繁体   English   中英

在VB.net中实现类似于EXCEL查找的功能

[英]Implementing a function similar to EXCEL Lookup in VB.net

我有很多代码,需要生成随机数,然后根据百分比选择选项。 我只需使用Mersenne Twister的实现并生成0到100之间的双精度,然后按选择大小写按百分比分配结果,就可以毫无问题地工作。 它工作正常,但是非常麻烦,说实话,我厌倦了每次都不断写出来的东西。

我更喜欢类似于EXCEL的Lookup Function的功能,在其中您可以提供两个数组,例如LOOKUP(5, {1,10,20,30,40}, {"1-10", "11-20", "21-30","31-40"})

在这种情况下它将返回:“ 1-10”,因为5在1-10之间。

有没有一种简单的方法可以使用LINQ来实现C#/ VB.Net版本? 我敢肯定一定有,但是我对如何实现这样的事情迷茫了。 与长选择案例语句相比,编写这一行代码要容易得多。

如果有比实现等效的EXCEL查找功能更好的方法,我也很想知道...

我假设您正在执行第二种形式的查找,因为如果第一个参数与第二个参数中传递的数组中的元素不完全匹配,则第一种将引发错误。

这应该工作:

Public Function LookUp(Of T)(ByVal value As IComparable, ByVal Values() As IComparable, ByVal Result() As T) As Object
    If Values Is Nothing Then Throw New ArgumentException("Values cannot be nothing")
    If Values.Length = 0 Then Throw New ArgumentException("Values can not be empty")
    If Result Is Nothing Then Throw New ArgumentException("Result cannot be nothing")
    If Values.Length = 0 Then Throw New ArgumentException("Result can not be empty")
    If Values.Length <> Result.Length Then Throw New ArgumentException("Values and Result must have the same length")
    Dim i As Integer = 0
    While i < Values.Length AndAlso value.CompareTo(Values(i)) < 0
        i += 1
    End While
    if i = Values.Length Then i-=1
    Return Result(i)
End Function

用法:

Dim Result as string = LOOKUP(5, {1,10,20,30,40}, {"1-10", "11-20", "21-30","31-40"})

使用LINQ或Array / List .FindIndex的方法很少,但是整数除法可能是最好的方法:

Dim d = 10.1, a = {1, 10, 20, 30, 40}, b = {"1-10", "11-20", "21-30", "31-40"}

Dim s1 = b(a.Count(Function(i) i <= d) - 1)

Dim s2 = b(Array.FindLastIndex(a, Function(i) i <= d))

Dim s3 = $"{d - d Mod 10 + 1}-{d - d Mod 10 + 10}"      ' "11-20"

我坐在那里思考了几分钟后,实际上自己想到了类似于@Alexander Higgins的答案。 我这样称呼它:

CaseLookup({41, 59, 80, 101}, {"Balanced", "PowerBack", "Receiving", "OneCut"}, 0, 100) 

基本上,我为下一项设置边界并循环查找小于的第一个索引,这意味着它将落在该范围内。 然后,我简单地从查找数组中获取与值相同的索引。

Public Shared Function CaseLookup(numArray As Array, lookupArray As Array, minVal As Double, maxval As Double) As String
        Dim result As String = ""
        Dim GetNum As Double = MT.GenerateDouble(minVal, maxval)

        If numArray.Length <> lookupArray.Length Then 'Checks to make sure the arrays are the same length
           Throw New Exception("numArray and lookupArray MUST be the same length!")
           Exit Function
        End If

        For i = 0 To numArray.Length - 1
            If GetNum < numArray(i) Then result = lookupArray(i).ToString()
        Next i
        Return result
    End Function

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM