18

I'm looking for something similar to numpy.linspace to generate an array of numbers based on a starting value, an ending value and the desired number of values in the array.

Example:

start=2.0, end=3.0, num=5
result = [2.0,  2.25,  2.5 ,  2.75,  3.0]

I've come across this, but it separates the range based on the steps between.

Does JavaScript have a built-in method to accomplish this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
james
  • 317
  • 1
  • 3
  • 6
  • 7
    Not built-in, no. You could write your own without too much hassle. – Mike Cluck Nov 07 '16 at 21:41
  • 2
    lodash has one: https://lodash.com/docs/4.16.6#range – njzk2 Nov 07 '16 at 21:43
  • @njzk2 not *quite* what OP asked, though ... – Matteo Tassinari Nov 07 '16 at 21:45
  • @MatteoTassinari the answer to the OP's question is "no". That's a bit short. Lodash may help anyway. Ramda has a `range` function too, but for integers only, so that would require a `map` on top of the range. (to get the exact thing, you'd need `var step = (end - start) / num; _.range(start, end + step, step);`) – njzk2 Nov 07 '16 at 21:54

2 Answers2

27

As others mentioned, there isn’t any built-in function in JavaScript, but here's one way you can implement it yourself. This specific example is a bit verbose so you can see exactly what's going on.

function makeArr(startValue, stopValue, cardinality) {
  var arr = [];
  var step = (stopValue - startValue) / (cardinality - 1);
  for (var i = 0; i < cardinality; i++) {
    arr.push(startValue + (step * i));
  }
  return arr;
}

console.log(makeArr(2, 3, 5));
console.log(makeArr(5, 10, 5));
console.log(makeArr(5, 10, 6));
console.log(makeArr(5, 31, 4));

If you want the numbers to be rounded to two decimal places, you can change the arr.push(...) line to the following:

arr.push(parseFloat((currValue + (step * i)).toFixed(2)));

Or

arr.push(Math.round((currValue + (step * i)) * 100) / 100);

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mhodges
  • 10,938
  • 2
  • 28
  • 46
  • Instead of temporarily converting the values to strings, you could also use `Math.round(val * 100) / 100` for rounding. – Felix Kling Nov 07 '16 at 22:36
  • @FelixKling Yeah, I thought about that after the fact, but didn't put it in because I had already edited a couple times. Since you mentioned it, though, I will add it as another option – mhodges Nov 07 '16 at 22:54
  • @mhodges Thanks, I'm fairly new to javascript so this will help me out. – james Nov 07 '16 at 22:59
11

You can make use of Array.from instead of manually pushing to the array:

function linspace(start, stop, num, endpoint = true) {
    const div = endpoint ? (num - 1) : num;
    const step = (stop - start) / div;
    return Array.from({length: num}, (_, i) => start + step * i);
}

Note that this won't work for num=1 and endpoint=true.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
STJ
  • 1,478
  • 7
  • 25