Таким образом, у одного из наших клиентов (аукциониста) есть набор странных приращений (также известных как лондонские приращения), где по существу они не соответствуют ни одному делимому числу, поэтому использование чего-то вроде: 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, и я надеюсь, что кто-то знает лучший способ сделать это.
// 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
, или просто наибольшее число из этого набора приращений, потому что код будет зацикливаться, пока не найдет выше и ниже число, поэтому, если у кого-то есть лучшая идея о том, как это сделать, он будет работать, но не зацикливаться?
Смотрите скриншот того, что я делал раньше:
Вы можете видеть, что он должен был зацикливаться 1865 раз, прежде чем нашел выше иниже суммы.
В любом случае, любые ваши идеи будут оценены.