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

时间:2017-07-09 02:00:06

标签: c# vb.net linq lookup

我有很多代码需要生成随机数,然后根据百分比选择选项。通过简单地使用Mersenne Twister的实现并生成0到100之间的双精度,然后使用select case分配结果,我可以毫无问题地工作。它工作得很好,但它非常麻烦而且说实话,我已经厌倦了每次都不断写出来。

我更喜欢类似于EXCEL查找功能的内容,您可以在其中提供两个数组,例如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查找功能,我也很想知道...

3 个答案:

答案 0 :(得分:0)

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

这应该有效:

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"})

答案 1 :(得分:0)

使用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"

答案 2 :(得分:0)

在我坐在那里思考了几分钟之后,我实际上想出了类似于@Alexander Higgins的回答。我称之为:

CREATE OPERATOR CLASS gin_int4range_ops
    DEFAULT FOR TYPE int4range[] USING gin AS
        OPERATOR        1       =(anyrange,anyrange),
        FUNCTION        1       lower(anyrange),
        FUNCTION        2       upper(anyrange),
        FUNCTION        3       isempty(anyrange),
        FUNCTION        4       lower_inc(anyrange),
        FUNCTION        5       upper_inc(anyrange);

create index ix_test on test using gin (data->val gin_int4range_ops); << error & needs to include the key

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

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