如何解决生成从最小到最大范围内均匀分布的整数列表
我正在尝试取一列填充数字并使用最小值和最大值生成过滤范围列表,供用户过滤表格。使用幼稚的方法最终会导致难以处理数字范围,而且我真的宁愿拥有可以工作的整数,而不管最小值/最大值如何。
我在多个地方看到过这个问题,我认为迄今为止我找到的最佳答案是 Stuart Ainsworth's number table answer,但我希望步骤非常圆。
例如,如果我需要生成 0-100000 的 4 个范围,则数字将是:
0 - 25000
25000 - 50000
50000 - 75000
75000 - 100000
但是,如果我的最小值和最大值是奇怪的数字,我会觉得使用范围很尴尬。
示例:如果我需要生成从 -1234 到 4321 的 5 个范围,则范围是:
-1234 - -123
-123 - 988
988 - 2099
2099 - 3210
3210 - 4321
我更喜欢这样的范围:
-1234 - 0 -1234 - 0 -1234 - -100
0 - 1000 0 - 1000 -100 - 1000
1000 - 2100 1000 - 2000 1000 - 2100
2100 - 3200 2000 - 3000 2100 - 3200
3200 - 4321 3000 - 4321 3200 - 4321
或类似的东西。范围需要接近彼此的大小,但更重要的是数字易于浏览和使用。
解决方法
这是一种计算覆盖范围所需的最小步长的方法,然后将其截断到 10 的最接近的十分之一,其中包括步长,然后返回从最小开始到最大结束的步进点,具有中间边界stepsize 距离和外边界稍高以包括最小值/最大值。
const range = (min,max,steps) => {
// minimum step size
stepsize = (max - min) / steps;
// increase the step size to a nice boundary
// for example,1/10th of the 10^n range that includes it
pow = Math.trunc(Math.log10(stepsize)) - 1;
stepsize = Math.trunc(stepsize / 10 ** pow) * 10 ** pow;
// round min to the same boundary
result = [min];
min = Math.trunc(min / 10 ** pow) * 10 ** pow;
for (let i = 0; i < steps - 1; i++) {
min += stepsize;
result.push(min);
}
result.push(max);
return result;
}
console.log(range(-1234,4321,5));
尼克的方法使用“算术级数”公式。这确实是解决这个问题的唯一方法。
以下解决方案考虑了@SpencerD 在单个算术级数如何无法获得所需结果方面的评论。除了递增 1,100 的“中间”部分之外,这不是一个直线序列。
因此,我发布这个答案是为了证明如果分阶段分解,所有的算术级数仍然是可能的。剩下的解释在代码注释中。
function lowerBound(actualValue,boundIncrement) {
// lets determine the min by an arithmetic progression formula
return Math.floor( actualValue / boundIncrement ) * boundIncrement
}
function upperBound(actualValue,boundIncrement) {
// lets determine the max by an arithmetic progression formula,hence the + 1 for the upper range
return (Math.floor( actualValue / boundIncrement ) + 1) * boundIncrement
}
function getRanges(min,max) {
let nextMin = min
// now lets use the helper funcs to determine the ranges based on "would prefer ranges like" from question
let ranges = [];
// if 1st range is negative,lets make it that value up to 0
if (min < 0) {
ranges.push([min,0]);
nextMin = 0;
}
// 2nd range requires special condition that it be on increment of 1,000
if ( max > nextMin) {
// so lets do this without conditions
ranges.push([nextMin,upperBound(nextMin,1000)]);
nextMin = upperBound(nextMin,1000);
}
// lets determine if there are subsequent ranges,on increment of 1,100
if (nextMin < max) {
while ( nextMin < max) {
ranges.push([nextMin,1100)])
nextMin = upperBound(nextMin,1100)
}
}
// lastly,lets make (overwrite) the max range's max with the max value instead
ranges[ ranges.length - 1][1] = max
return ranges;
}
function test() {
console.log( getRanges( parseInt(document.getElementById("min").value),parseInt(document.getElementById("max").value) ) );
}
Enter min: <input type="text" id="min" value="-1234">
<br>
Enter max: <input type="text" id="max" value="4321">
<br>
<button onclick="test()">Console.log()</button>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。