使用LINQ获取两个值之间整数的倍数序列

eufgjt7s  于 2022-12-06  发布在  其他
关注(0)|答案(5)|浏览(149)

好吧,标题很丑,但问题很简单:
我有一个WPF控件,我想在其中显示地块线。我的“视口”有它的限制,这些限制(例如,对象坐标中的底部和顶部值)是doubles
因此,我希望以每5的倍数绘制一条线。如果我的视口从-8.3到22.8,我将得到[-5, 0, 5, 10, 15, 20]
我想使用LINQ,它似乎是自然的候选人,但无法找到一种方法...
我的设想大致如下:

int nlines = (int)((upper_value - lower_value)/step);
var seq = Enumerable.Range((int)(Math.Ceiling(magic_number)), nlines).Select(what_else);

给定值为(double)lower_value(double)upper_value(int)step

kokeuurv

kokeuurv1#

Enumerable.Range应该可以做到这一点:

Enumerable.Range(lower_value, upper_value - lower_value)
          .Where(x => x % step == 0);
kxe2p93d

kxe2p93d2#

请尝试以下代码:

double lower_value = -8.3;
double upper_value = 22.8;
int step = 5;

int low = (int)lower_value / step;
int up = (int)upper_value / step;

var tt = Enumerable.Range(low, up - low + 1).Select(i => i * step);

EDIT此代码适用于lower_value的所有负值和可被step整除的正值。要使其也适用于所有其他正值,应应用以下更正:

if (lower_value > step * low)
    low++;
rxztt3cl

rxztt3cl3#

第一个问题是确定距离起点最近的步长值因子。一些简单的算法可以推导出该值:

public static double RoundToMultiple(double value, double multiple)
{
    return value - value % multiple;
}

然后创建一个范围内给定值的所有因子的序列,迭代器块非常适合:

public static IEnumerable<double> FactorsInRange(
    double start, double end, double factor)
{
    var current  = RoundToMultiple(start, factor);
    while (start < end)
    {
        yield return start;
        current = current + factor;
    }
}

如果你有Generate method from MoreLinq,那么你可以在没有显式迭代器块的情况下写这个:

public static IEnumerable<double> FactorsInRange(
    double start, double end, double factor)
{
    return Generate(RoundToMultiple(start, factor),
        current => current + factor)
        .TakeWhile(current => current < end);
}
7gs2gvoe

7gs2gvoe4#

为了避免必须枚举 * 每个 * 数字,您必须在LINQ之外:

List<int> steps;
int currentStep = (lower_value / step) * step; //This takes advantage of integer division to "floor" the factor
steps.Add(currentStep);
while (currentStep < upper_value)
{
   currentStep += step;
   steps.Add(currentStep);
}
uoifb46i

uoifb46i5#

我对代码做了一些调整。

private List<int> getMultiples(double lower_value, double upper_value, int step) {
        List<int> steps = new List<int>();
        int currentStep = (int)(lower_value / step) * step; //This takes advantage of integer division to "floor" the factor
        steps.Add(currentStep);
        while (currentStep <= upper_value) {
            steps.Add(currentStep);
            currentStep += step;
        }
        return steps;
    }

相关问题