使用LINQ获取两个值之间整数的倍数序列
本文关键字:整数 之间 两个 获取 LINQ 使用 | 更新日期: 2023-09-27 17:58:51
好吧,标题很难看,但问题很简单:
我有一个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
。
Enumerable.Range应该做到这一点:
Enumerable.Range(lower_value, upper_value - lower_value)
.Where(x => x % step == 0);
试试这个代码:
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);
编辑此代码适用于lower_value
的所有负值和可被step
整除的正值。为了使其也适用于所有其他正值,应应用以下校正:
if (lower_value > step * low)
low++;
第一个问题是从起点确定步长值的最接近因子。一些简单的算术可以推导出这个值:
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;
}
}
如果你有来自MoreLinq的Generate方法,那么你可以在没有显式迭代器块的情况下写这个:
public static IEnumerable<double> FactorsInRange(
double start, double end, double factor)
{
return Generate(RoundToMultiple(start, factor),
current => current + factor)
.TakeWhile(current => current < end);
}
为了避免枚举每个数字,您必须退出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);
}
我对代码进行了一些调整。
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;
}