Reputation: 2650
I have an interval [0; max]
and I want to split it into a specific number of sub-intervals. For this, i wrote a function called getIntervalls(max, nbIntervals)
where max
is the max element in my first interval and nbIntervals
is the number of expected sub-intervals.
For example:
getIntervalls(3, 2)
should return [[0,1], [2,3]]
, getIntervalls(6, 2)
should return [[0,3], [4,6]]
,getIntervalls(8, 3)
should return [[0,2], [3,5], [6,8]]
,getIntervalls(9, 3)
should return [[0,3], [4,7], [8,9]]
,Here is my function:
function getIntervalls(max, nbIntervalls) {
var size = Math.ceil(max / nbIntervalls);
var result = [];
if (size > 1) {
for (let i = 0; i < nbIntervalls; i++) {
var inf = i + i * size;
var sup = inf + size < max ? inf + size: max;
result .push([inf, sup]);
}
} else {
result.push([0, max]);
}
return result;
}
console.log(JSON.stringify(getIntervalls(7, 2)));
It work properly, and shows this output:
[[0,4],[5,7]]
When I change the parameters to 7 and 3, it shows:
[[0,3],[4,7],[8,7]]
instead of
[[0,2],[3,5],[6,7]]
Would anyone can help me? Thank you in advance. An ES6 syntax will be appreciated! :)
Upvotes: 7
Views: 4259
Reputation: 745
For me, this is the perfect function for that.
It allows you to get the intervals between two numbers, and the last interval always goes to the max.
function getIntervals(min, max, nbIntervals) {
let size = Math.floor((max - min) / nbIntervals);
let result = [];
if (size <= 0) return [min, max];
for (let i = 0; i < nbIntervals; i++) {
let inf = min + (i * size);
let sup = ((inf + size) < max) ? inf + size : max;
if (i === (nbIntervals - 1)) {
if (sup < max) sup = max;
}
result.push([inf, sup]);
if (sup >= max) break;
}
return result;
}
Upvotes: 2
Reputation: 418
You need to use Math.round()
for take the nearest integer of the decimal number of the size
of interval. Also, you need to descrease a one the max
for size
calculation to take account of the effective number of interval.
Here the modification of your code :
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;
}
Note that it respect the wanted number of interval, so some case of couple of number can result
[..., [n-2,n-1], [n,n]]
.
Hope this helps!
Upvotes: 4
Reputation: 2000
You need to change the size calculation from Math.ceil()
to Math.floor()
, because of ceil
it takes size +1 than what you need.
I have made modification to your code, here it will work.
function getIntervalls(max, nbIntervalls) {
var size = Math.floor(max / nbIntervalls);
var result = [];
if (size > 0) {
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 (sup >= max) {
break;
}
}
} else {
result.push([0, max]);
}
return result;
}
console.log(JSON.stringify(getIntervalls(10, 5)));
Hope this helps!
Upvotes: 2
Reputation: 122027
You could check if i
is zero for first element and if next increment is larger then max for second element. Also you can check if first element is smaller then max.
function getIntervalls(max, nInt) {
const c = Math.floor(max / nInt);
const r = [];
for (var i = 0; i <= max; i += c) {
const a = i == 0 ? i : i += 1;
const b = i + c > max ? max : i + c;
if (a < max) r.push([a, b])
}
return r;
}
console.log(JSON.stringify(getIntervalls(3, 2)));
console.log(JSON.stringify(getIntervalls(6, 2)));
console.log(JSON.stringify(getIntervalls(8, 3)));
console.log(JSON.stringify(getIntervalls(9, 3)));
console.log(JSON.stringify(getIntervalls(7, 2)));
console.log(JSON.stringify(getIntervalls(7, 3)));
Upvotes: 3