Reputation: 65
I have an array of min
and max
. I need a solution which is similar to this question but I have a min
value as well. For example, I have an array [108090, 498090]
. How do I add the min
condition in the following function?
function getIntervalls(max, nbIntervalls) {
var size = Math.round((max-1) / nbIntervalls);
var result = [];
for (let i = 0; i < nbIntervalls; i++) {
var inf = i + i * size;
var sup = inf + size < max ? inf + size: max;
result.push([inf, sup]);
if(inf >= max || sup >= max)break;
}
return result;
}
getIntervals(108090, 5)
The output of the above function is:
[
[
0,
99618
],
[
99619,
199237
],
[
199238,
298856
],
[
298857,
398475
],
[
398476,
498090
]
]
But I want to send the min
value also. So my required should be like [108090, ...], [..,..], [..,..], [..,..], [..,498090]
.
Thanks in advance!!!
Upvotes: 2
Views: 1685
Reputation: 50787
Note that this can also be done with a simple recursion. Something like this might be all you need:
const getIntervals = (min, max, count, end = min + (max - min) / count) =>
count < 1 ? [] : [[min, end], ... getIntervals (end, max, count - 1)]
log (getIntervals (20, 62, 3))
log (getIntervals (108090, 498090, 5))
<script>const log = (o) => console .log (JSON.stringify(o))</script>
We recur on the number of subgroups still to create (count
), calculating the end of the interval using the max
, min
, and count
arguments.
But this does not increment the start of one group from the end of the previous one. We can do that with a minor adjustment:
const getIntervals = (min, max, count, end = min + (max - min + 1) / count - 1) =>
count < 1
? []
: [[min, end], ... getIntervals (end + 1, max, count - 1)]
log (getIntervals (21, 62, 3))
log (getIntervals (108091, 498090, 5))
<script>const log = (o) => console .log (JSON.stringify(o))</script>
This does the same thing as the above, but recurs using one more than the end of the previous group as the new minimum, rather than just using that end value as above.
Here we had to adjust the start value (or the end one) in order to get our counts correct and avoid non-integer endpoints. We switched from 108090 - 498090
to 108091 - 498090
. This involves knowing how many values are in the range, and ensuring the count properly divides into that number.
If for instance, we tried getIntervals (21, 64, 6)
, we would get this:
[
[21, 27.333333333333332],
[28.333333333333332, 34.666666666666664],
[35.666666666666664, 42],
[43, 49.333333333333336],
[50.333333333333336, 56.66666666666667],
[57.66666666666667, 64]
]
We could do something a little different that will always work without the fractional endpoints, but will have groups that aren't exactly the same size:
const getIntervals = (min, max, count, end = min + Math.ceil ((max - min + 1) / count) - 1) =>
count < 1 ? [] : [[min, end], ... getIntervals (end + 1, max, count - 1)]
log (getIntervals (21, 62, 3))
log (getIntervals (108090, 498090, 5))
log (getIntervals (21, 64, 6))
<script>const log = (o) => console .log (JSON.stringify(o))</script>
We introduce Math.ceil
, and now getIntervals (21, 66, 6)
returns the nicer:
[
[21, 28],
[29, 36],
[37, 43],
[44, 50],
[51, 57],
[58, 64]
]
here we have some number of results with n
entries followed by others with n - 1
entries. Here we have two groups with eight entries each followed by four others with seven each. If we switched from Math .ceil
to Math .floor
, we would get the smaller groups first, and then the longer ones. But the important thing is that all the groups are within one element of the same size as the others.
Each of these possibilities uses a simple recursion for the job. It's pretty powerful!
Upvotes: 1
Reputation: 29
You can simply add min
condition in interval size & inf calculation as
function getIntervalls(min, max, nbIntervalls) {
var size = Math.round((max-min-1) / nbIntervalls);
var result = [];
var inf = min;
var sup = 0
for (let i = 0; i < nbIntervalls; i++) {
inf = (i == 0)? inf : sup + 1;
sup = (inf + size) < max ? inf + size: max;
result.push([inf, sup]);
if(sup >= max) break;
}
return result;
}
Upvotes: 1
Reputation: 2293
min
value to the max
value, so you are now working with numbers linearly related to the interval you passed as an argument.function getIntervals(min, max, nbIntervalls) {
max -= min; // --------------------------> subtract min
var size = Math.round((max-1) / nbIntervalls);
var result = [];
for (let i = 0; i < nbIntervalls; i++) {
var inf = i + i * size;
var sup = inf + size < max ? inf + size: max;
result.push([inf + min, sup + min]); // --------------------> add again min
if(inf >= max || sup >= max)break;
}
return result;
}
console.log(getIntervals(108090, 498090, 5))
Upvotes: 2