如何使用上限和下限从数组中提取值?

时间:2012-02-01 07:31:53

标签: c# arrays

给定两个数组,我需要根据范围(实际值)在arrayA中的位置从arrayB中提取值。

Index     0    1  2    3  4    5  6   7   8     9  10   11  12
-------------------------------------------------------------
ArrayA = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4,  4.5,  5, 5.5,  6}
ArrayB = {1, 0.2, 3,   4, 5,   6,5.5,  8,  9,11.1, 11,  12,  3}

鉴于以下范围,我需要提取以下结果

RangeToExtract*  IndexInArrayA  Expected Values To Extract
--------------  -------------  --------------------------
0 -> 1          [0,2]          1,0.2,3
1 -> 3          [3,6]          4,5,6,5.5
3 -> 5          [7,10]         5.5,8,9,11.1,11
1 -> 5          [3,10]         4,5,6,5.5,8,9,11.1,11
3 -> 10         [7,12]         8,9,11.1,11,12,3 

* Refers to the actual values in ArrayA

注意:给定RangeToExtract (0->1),确定ArrayA中这些值所在的索引,结果是(0->1)映射到[0,2](值1在ArrayA中的位置2) )

我只是认为存在以下特殊情况(不确定是否还有更多)

  1. 下限等于零和
  2. 当ArrayA中不存在上限时
  3. 更多信息:

    • 两个数组的大小相同
    • ArrayA将始终排序

    代码:

    private double[] GetRange(double lower, double upper)
    { 
        var myList = new double[ArrayA.Length];
        var lowerIndex = Array.IndexOf(ArrayA, lower);
        var upperIndex = Array.IndexOf(ArrayA, upper);
    
        // special case 1
        if (lowerIndex != 0)
        {
            lowerIndex = lowerIndex + 1; 
        }
    
        // special case 2
        if (upperIndex == -1)
        {
            upperIndex = ArrayA.Length-1; 
        }
    
        for (int i = lowerIndex; i <= upperIndex; i++)
        {
            myList[i] = ArrayB[i];
        }
        return myList;
    }
    

    鉴于上述代码,是否考虑了所有特殊情况?有没有更好的方法来编写上面的代码?

2 个答案:

答案 0 :(得分:0)

雅浦岛!有一个更好的方法,有可爱的LINQ。我把它放在两个表格中。首先看起来很复杂,但根本不是!相信我;)

第一个步骤中,你必须取出那些A'indexes他们的值落入你的范围(我称之为min...max),根据你的例子,我得到了您的范围关闭 下边界关闭 上方,我的意思是您提到{{1实际上它是3 -> 5!它不包含5.无论如何,这不是问题。

这可以通过遵循LINQ

来完成
[3, 5)

第一次选择,生成int[] selectedIndexes = a.Select((value, index) => new { Value = value, Index = index }). Where(aToken => aToken.Value > min && aToken.Value <= max). Select(t => t.Index).ToArray<int>(); 对的集合,第一个是数组元素,第二个是数组中元素的索引。我认为这是你问题的主要伎俩。因此,它为您提供了使用与常规值相同的索引的能力。

最后在第二次选择中,我将整个索引包装成一个整数数组。因此,在此之后,您拥有整个索引,它们的值落在给定范围内。

现在第二步

当你得到这些索引时,你必须从A中选择的索引下的 B 中选择整个元素。同样的事情应该在B上完成。这意味着我们再次选择B元素进入[Value,Index]对的集合,然后我们从A中选择那些他们的索引存在于选定索引中的人。这可以通过以下方式完成:

[Value, Index]

好的,所以首先选择是我在第一部分谈到它的那个,然后查看double[] selectedValues = b.Select((item, index) => new { Item = item, Index = index }). Where(bToken => selectedIndexes.Contains(bToken.Index)). Select(d => d.Item).ToArray<double>(); 部分,检查where的索引是否是哪个是bToken(来自A)中是否存在B的元素!

最后,我将两个代码包装成一个,如下所示:

selectedIndexes

为我买啤酒,如果它有用:)

答案 1 :(得分:0)

我不知道你是否还有兴趣,但我看到了这个,我喜欢这个挑战。如果您使用.Net 4(具有Enumberable.Zip方法),有一种非常简洁的方法(根据进一步信息下的条件):

arrayA.Zip(arrayB, (a,b) => new {a,b})
    .Where(x => x.a > lower && x.a < upper)
    .Select (x => x.b)

您可能希望使用>=<=来进行范围比较。