因此,我们的一位客户(拍卖师)有一组怪异的增量(也称为伦敦增量),在本质上,它们不符合任何可整的数,因此使用类似Math.round(number / increment) * increment
的东西工作。
增量
From: 100, To: 299, Increment: 10
From: 300, To: 319, Increment: 20
From: 320, To: 379, Increment: 30
From: 380, To: 419, Increment: 20
这种事情还在继续。
因此,使用类似311
的数字应四舍五入为320
。现在,我有了这段代码,它可以正常工作,并且可以按预期对321 => 350
和363 => 380
进行四舍五入。
我担心的是,它不是快速和/或可持续的,并且需要舍入的大量数字会变得越来越慢。显然,此功能必须与Math.round()
一样快,但它不会,但要尽可能快。现在,只要我能正常工作,我的工作方式基本上就是循环X次(x是任意数字,因此我将其设置为9999999,我希望有人知道这样做的更好方法。 / p>
// Get increment amount
window.getIncrement = (num) => {
var num = parseInt(num);
for (var i = 0; i < window.increments.length; i++) {
if (num >= parseInt(window.increments[i].from) && num <= parseInt(window.increments[i].to)) {
return parseInt(window.increments[i].increment);
}
}
}
// Get increment start value
window.getIncrementStartValue = (num) => {
var num = parseInt(num);
for (var i = 0; i < window.increments.length; i++) {
if (num >= parseInt(window.increments[i].from) && num <= parseInt(window.increments[i].to)) {
return parseInt(window.increments[i].from);
}
}
};
// Custom round up function
const roundToNearestIncrement = (increment, number, roundDown) => {
var incrementStart = parseInt(window.getIncrementStartValue(number));
var increment = parseInt(increment), number = parseInt(number);
console.log(incrementStart, increment, number);
// So now we have a start value, check the direction of flow
var lastBelow = false, firstAbove = false;
for (var i = 0; i < 9999999; i++) {
var incrementRounder = incrementStart + (increment * i);
if (incrementRounder === number) { return number; }
if (incrementRounder < number) { lastBelow = incrementRounder; }
if (incrementRounder > number) { firstAbove = incrementRounder; }
if (lastBelow !== false && firstAbove !== false) { break; }
console.log('Loop #' + i + ', Below: ' + lastBelow + ', Above: ' + firstAbove);
}
return !roundDown ? firstAbove : lastBelow;
}
然后您像这样使用它:
// Example usage
var num = 329;
var inc = getIncrement(num);
console.log('Rounded: ' + roundToNearestIncrement(inc, num) + ', Expected: 350');
现在,正如我所说的,它可以很好地工作,但是我担心的是,如果数字使用1,234,567
之类的大数字,或者仅使用该增量集的最大数字,它将减慢Node进程的速度,因为代码会循环直到找到上面和下面的数字,因此,如果有人对如何执行此操作有更好的了解,它将起作用但不会循环?
查看我之前做过的截图:
您可以看到它必须循环1865次才能找到上下数量。
无论如何,您的任何想法都会受到赞赏。
答案 0 :(得分:0)
有两种方法可以使速度更快
1。您可以存储一个非常大的哈希,将所有可能的值和舍入结果。这将使用很多开销,但最快。这意味着您将使用类似于
的哈希rounded = []; rounded[0]=0 ... rounded[100] = rounded[101] = ... = rounded[109] = 110 ... and so on.
当然,此解决方案取决于表的大小。
2。基于突破点构建binary search tree,然后搜索该树。如果树是平衡的,则将以O(log(n))进行搜索。
答案 1 :(得分:0)
如果我正确理解了这个问题:
const findNearestThreshold = (number) => thresholdsArray
.find(threshold => (threshold >= number));
答案 2 :(得分:0)
仅基于增量数组的解决方案。
const steps = [
{ from: 100, increment: 10}, // I don't need 'to' property here
{ from: 300, increment: 20},
{ from: 320, increment: 30},
{ from: 380, increment: 20},
]
const roundUp = x => {
const tooLargeIndex = steps.findIndex(({from}) => from > x);
const { from, increment } = steps[tooLargeIndex - 1];
const difference = x - from;
return from + Math.ceil(difference / increment) * increment;
}
console.log(300, roundUp(300));
console.log(311, roundUp(311));
console.log(321, roundUp(321));