Вот решение, которое всегда будет работать, пока вы оставляете достаточно места в выбранном диапазоне / разделении / количестве. И это намного эффективнее, чем когда-то l oop. Он не просто продолжает попытки, пока не получит правильное решение, он фактически выполняет математические вычисления, чтобы убедиться, что все правильно с первого раза.
Это происходит за счет склонности к определенным числам больше, чем к другим (например, from + (i * separation)
), так что примите это к сведению.
function getSeparatedRadomInts(from, through, separation, count) {
if(through < from) return getSeparatedRadomInts(through, from, separation, count);
if(count == 0) return [];
if(separation == 0) return !!console.log("Please allow enough room in the range/separation/count you choose.");
//pick values from pool of numbers evenly stepped apart by units of separation... adding 1 to from and through if from is 0 so we can divide properly
var smallFrom = Math.ceil((from || 1) / separation);
var smallThrough = Math.floor((through + (from == 0)) / separation);
var picks = randoSequence(smallFrom, smallThrough).slice(-count).sort((a, b) => a - b);
if(picks.length < count) return !!console.log("Please allow enough room in the range/separation/count you choose.");
for (var i = 0; i < picks.length; i++) picks[i] *= separation;
//go through each pick and randomize with any wiggle room between the numbers above/below it... adding 1 to from and through if from is 0
for (var i = 0; i < picks.length; i++) {
var lowerBound = picks[i - 1] + separation || from || 1;
var upperBound = picks[i + 1] - separation || (through + (from == 0));
picks[i] = rando(lowerBound, upperBound);
}
//subtract 1 from all picks in cases where from is 0 to compensate for adding 1 earlier
for (var i = 0; i < picks.length; i++) if(from == 0) picks[i] = picks[i] - 1;
return picks;
}
console.log(getSeparatedRadomInts(10, 290, 20, 12));
<script src="https://randojs.com/1.0.0.js"></script>
Для ясности: from
- минимальное значение диапазона, through
- максимальное значение диапазона, separation
- минимальное значение, которое должно быть отдельно друг от друга (например, разделение 20
может привести к [10, 30, 50, 70]
), а count
- это количество значений, которое вы хотите выбрать.
Я использовал rando js в этом коде, чтобы упростить случайность и облегчить чтение, поэтому, если вы хотите использовать этот код, просто не забудьте вставить его в заголовок вашего HTML документа:
<script src="https://randojs.com/1.0.0.js"></script>