70

Is there a way to generate sequence of characters or numbers in javascript?

For example, I want to create array that contains eight 1s. I can do it with for loop, but wondering whether there is a jQuery library or javascript function that can do it for me?

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • Whats wrong with using the `for` loop? – Russell Dias Sep 20 '10 at 12:39
  • 1
    Is there any necessity for a library to do this job ? I don't think so =) –  Sep 20 '10 at 12:41
  • Not at all. This is clearly something best solved at a language level, not a library level. I've modified the question accordingly. – Dagg Nabbit Sep 20 '10 at 12:43
  • 3
    I think this is a very valid question, there are languages that do this out-of-box, if you have to create 3 dropdowns day/month/year then 3 for loops seems messy, however it also seems like it's the only quick way to do it – Rob May 23 '13 at 11:30
  • Possible duplicate of [Does JavaScript have a method like "range()" to generate an array based on supplied bounds?](https://stackoverflow.com/questions/3895478/does-javascript-have-a-method-like-range-to-generate-an-array-based-on-suppl) – Evan Carroll Mar 10 '18 at 21:37

23 Answers23

67

The original question was edited. So the updated example answers:

To fill the same content:

Array(8).fill(1)
//=> [1, 1, 1, 1, 1, 1, 1, 1]

To fill sequential numbers, starting from 5:

Array(8).fill().map((element, index) => index + 5)
//=> [5, 6, 7, 8, 9, 10, 11, 12]

To fill sequencial characters, starting from 'G':

Array(8).fill().map((element, index) => String.fromCharCode('G'.charCodeAt(0) + index)) 
//=> ["G", "H", "I", "J", "K", "L", "M", "N"]
g.sui
  • 1,550
  • 3
  • 15
  • 20
45

Without a for loop, here is a solution:

Array.apply(0, Array(8)).map(function() { return 1; })

The explanation follows.

Array(8) produces a sparse array with 8 elements, all undefined. The apply trick will turn it into a dense array. Finally, with map, we replace that undefined the (same) value of 1.

Ariya Hidayat
  • 12,523
  • 3
  • 46
  • 39
  • That's really cool, although I'm not quite understanding it. How exactly does the Array.apply turn that array into a dense array? I'd love to understand exactly what's going on in that trick. – Alexandr Kurilin Feb 07 '13 at 06:47
  • 6
    Here is a good short explanation on arrays: http://www.2ality.com/2012/06/dense-arrays.html. – Ariya Hidayat Feb 10 '13 at 04:39
  • 7
    I love this. Found it on a search and it was exactly what I was looking for. Here is a slight modification to create a series: `Array.apply(0, Array(8)).map(function(_,b) { return b + 1; }) => [1, 2, 3, 4, 5, 6, 7, 8]` the args to map are the `element, index, array` for other fun uses. – stoolio Apr 10 '15 at 01:54
21

One liner:

new Array(10).fill(1).map( (_, i) => i+1 )

Yields:

[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
mendezcode
  • 857
  • 8
  • 7
19

You can make your own re-usable function I suppose, for your example:

function makeArray(count, content) {
   var result = [];
   if(typeof content == "function") {
      for(var i = 0; i < count; i++) {
         result.push(content(i));
      }
   } else {
      for(var i = 0; i < count; i++) {
         result.push(content);
      }
   }
   return result;
}

Then you could do either of these:

var myArray = makeArray(8, 1);
//or something more complex, for example:
var myArray = makeArray(8, function(i) { return i * 3; });

You can give it a try here, note the above example doesn't rely on jQuery at all so you can use it without. You just don't gain anything from the library for something like this :)

Moritz
  • 432
  • 5
  • 15
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • i think `result.push(i);` should be ` result.push(content);` ahh... edited already.. – Gabriele Petrioli Sep 20 '10 at 12:43
  • Hey, thanks for this. Thought there could be something similar to what's available in MatLab, i.e. create vector of some length that will contain certain elements. –  Sep 20 '10 at 13:02
19

This is the simplest one by far

const sequence = [...Array(10).keys()]
console.log(sequence)

Output : [0,1,2,3,4,5,6,7,8,9]

Goutham J.M
  • 1,726
  • 12
  • 25
16
for (var i=8, a=[]; i--;) a.push(1);
Dagg Nabbit
  • 75,346
  • 19
  • 113
  • 141
  • 7
    needs moar jquery? hmmm, does this work: `for (var i=8, a=[]; i--;) a.push($(1));` – Dagg Nabbit Sep 20 '10 at 12:44
  • @no just kidding, OP may not be satisfied, 'cause it is missing jQuery, lol. In your comment `a.push($(1))`, it pushes jQuery objects into the array not the numbers :) –  Sep 20 '10 at 12:52
  • @Avinash, I know, was just screwing around ;) – Dagg Nabbit Sep 20 '10 at 19:08
15

2016 - Modern Browser functionality has arrived. No need for jquery all the time.

Array.from({length: 8}, (el, index) => 1 /* or index */);

You can substitute the arrow function with a simple callback function to reach a slightly wider range of supported browsers. It's, for me at least, the easiest way to iterate over an initialized array in one step.

Note: IE is not supported in this solution, but there is a polyfill for that at developer.mozilla.org/...

Tom Siwik
  • 992
  • 9
  • 22
12

Using Jquery:


$.map($(Array(8)),function(val, i) { return i; })

This returns:

[0, 1, 2, 3, 4, 5, 6, 7]

$.map($(Array(8)),function() { return 1; })

This returns:

[1, 1, 1, 1, 1, 1, 1, 1]

6

range(start,end,step): With ES6 Iterators

You can easily create range() generator function which can function as an iterator. This means you don't have to pre-generate the entire array.

function * range ( start, end, step ) {
  let state = start;
  while ( state < end ) {
    yield state;
    state += step;
  }
  return;
};

Now you may want to create something that pre-generates the array from the iterator and returns a list. This is useful for functions that accept an array. For this we can use Array.from()

const generate_array = (start,end,step) => Array.from( range(start,end,step) );

Now you can generate a static array easily,

const array = generate_array(1,10,2);

But when something desires an iterator (or gives you the option to use an iterator) you can easily create one too.

for ( const i of range(1, Number.MAX_SAFE_INTEGER, 7) ) {
  console.log(i)
}
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
3

A sequence is a stream, which computes the value when it is needed. This requires only a bit memory but more CPU time when the values is used.

An array is a list of precomputed values. This takes some time before the first value can be used. And it requires much memory, because all possible values of the sequence must be stored in memory. And you have to define an upper limit.

This means, that in most cases it is no good idea to create an array with sequence values. Instead it is better to implement the sequence as a real sequence, which is limited just by the word length of the CPU.

function make_sequence (value, increment)
{
  if (!value) value = 0;
  if (!increment) increment = function (value) { return value + 1; };

  return function () {
    let current = value;
    value = increment (value);
    return current;
  };
}

i = make_sequence()
i() => 0
i() => 1
i() => 2

j = make_sequence(1, function(x) { return x * 2; })
j() => 1
j() => 2
j() => 4
j() => 8
ceving
  • 21,900
  • 13
  • 104
  • 178
  • upvoting because I'm trying to get my head around closures and I think this is a really good example, amiright? – stib Oct 11 '16 at 12:31
  • 1
    @stib Exactly. The anonymous function returned by `make_sequence` captures the environment containing `value` and `increment`, which means the function has read and write access to the variables. That's all what matters. A (lexical) closure is nothing more than a dynamically generated function having access to the environment visible at the code position, where the function has been created. There are also [dynamically scoped](http://stackoverflow.com/questions/1047454/what-is-lexical-scope) closures but apart from Emacs they are rarely used. – ceving Oct 11 '16 at 13:32
1
The fastest way to define an array of 8 1s is to define it-
var A= [1, 1, 1, 1, 1, 1, 1, 1];

// You'd have to need a lot of 1s to make a dedicated function worthwhile.

// Maybe in the Matrix, when you want a lot of Smiths:

Array.repeat= function(val, len){
    for(var i= len, a= []; i--; ) a[i]= val;
    return a;
}
var A= Array.repeat('Smith',100)

/*  returned value: (String)
Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith
*/
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • should that be `for(var i= len; a= []; i--; ) a[i]= val;` (semicolon after len instead of comma)? – stib Oct 11 '16 at 12:29
1

in ES6 simple solution:

seq = (from, len, step = 1) => Array.from({length: len}, (el, i) => from + (i * step));
Marek Lisiecki
  • 498
  • 6
  • 10
1

Here's a benchmark where the comment after each option shows the median time of a thousand runs in ms:

let opt=[
  'Array(n).fill().map((_,i)=>i)', // 2.71
  'Array(n).fill().map(function(_,i){return i})', // 2.73
  'let o=[];for(let i=0;i<1e5;i++)o[i]=i', // 3.29
  'let o=[];for(let i=0;i<1e5;i++)o.push(i)', // 3.31
  'let o=[];for(let i=0,n2=n;i<n2;i++)o[i]=i', // 3.38
  'let o=[];for(let i=0;i<n;i++)o[i]=i', // 3.57
  'Array.apply(null,Array(n)).map(Function.prototype.call.bind(Number))', // 3.64
  'Array.apply(0,Array(n)).map((_,i)=>i)', // 3.73
  'Array.apply(null,Array(n)).map((_,i)=>i)', // 3.77
  'o2=[];for(let i=0;i<n;i++)o2[i]=i', // 4.42
  '[...Array(n).keys]', // 7.07
  'Array.from({length:n},(_,i)=>i)', // 7.13
  'Array.from(Array(n),(_,i)=>i)', // 7.23
  'o3=[];for(i3=0;i3<n;i3++)o3[i3]=i3' // 24.34
]

let n=1e5
opt.sort(()=>Math.random()-.5)
for(let opti of opt){
  let t1=process.hrtime.bigint()
  eval(opti)
  let t2=process.hrtime.bigint()
  console.log(t2-t1+'\t'+opti)
}

The for loop became a lot faster when I used block-scoped variables instead of global variables.

I used median time instead of mean because occasionally a single run can take much longer than typical runs which distorts the mean time.

I ran the benchmark like for i in {1..1000};do node seqbench.js;done, because when I invoked the script only once but I ran each option 1000 times inside the script, it was affected by some kind of an optimization where the for loops became the fastest options.

nisetama
  • 7,764
  • 1
  • 34
  • 21
0

Typescript method based on Ariya Hidayat code:

/**
 * Generates sequence of numbers from zero.
 * @ param {number} count Count of numbers in result array.
 * @ return {Array<number>} Sequence of numbers from zero to (count - 1).
 */
public static sequence(count: number): Array<number>
{
    return Array.apply(0, Array(count)).map((x, i) =>
    {
        return i;
    });
}
prespic
  • 1,635
  • 1
  • 17
  • 20
0

If like me you use linspace a lot, you can modify your version of linspace easily like so:

function linSeq(x0, xN) {
    return linspace(x0, xN, Math.abs(xN-x0)+1);
}

function linspace(x0, xN, n){

    dx = (xN - x0)/(n-1);
    var x = [];
    for(var i =0; i < n; ++i){
        x.push(x0 + i*dx);
    }

    return x;
}

You can then use linSeq in any direction, e.g. linSeq(2,4) generates 2,3,4 while linSeq(4,2) generates 4,3,2.

Randhir Rawatlal
  • 365
  • 1
  • 3
  • 13
0

Another method, for those how are memory saving pedant:

Array.apply(null, Array(3)).map(Function.prototype.call.bind(Number))
Slavik Meltser
  • 9,712
  • 3
  • 47
  • 48
0
var GetAutoNumber = exports.GetAutoNumber = (L) => {
    let LeftPad = (number, targetLength) => {
        let output = number + '';
        while (output.length < targetLength) {
            output = '0' + output;
        }
        return output;
    }
    let MaxNumberOfGivenLength = "";
    for (let t = 0;t < L;t++) {
        MaxNumberOfGivenLength = MaxNumberOfGivenLength + "9"
    }
    let StartTime = +new Date();
    let Result = [];
    let ReturnNumber;
    for (let i = 1;i <= MaxNumberOfGivenLength;i++) {
        Result.push(LeftPad(i, L))
    }
    for (let k = 0;k != 26;k++) {
        for (let j = 0;j <= 999;j++) {
            Result.push(String.fromCharCode(k + 65) + LeftPad(j, (L - 1)));
        }
    }
    console.log(Result.length)
    return Result;
}
GetAutoNumber(3)

It will generate result like 001-999, A01-A99... Z01-Z99

Parshav Shah
  • 203
  • 2
  • 9
0

This is a good option

var result = [];
for (var i = 1; i != 4; ++i) result.push(i)

check here for more options https://ariya.io/2013/07/sequences-using-javascript-array

Anoop P S
  • 754
  • 1
  • 12
  • 31
0

If you want to produce a sequence of equal numbers, this is an elegant function to do it (solution similar to other answer):

seq = (n, value) => Array(n).fill(value)

If you want to produce a sequence of consecutive numbers, beginning with 0, this a nice oneliner:

seq = n => n<1 ? [] : [...seq(n-1), n]

This is for different start values and increments:

seq2 = (n, start, inc) => seq(n).map(i => start + inc * i)
Donat
  • 4,157
  • 3
  • 11
  • 26
0

Javascript ES6 in action :)

Array(8).fill(1)

console.log(Array(8).fill(1))
Waelsy123
  • 594
  • 2
  • 13
0

I like this one.

function* generate() {
  let index = 0;

  while (true) {
    index++;
    yield String.fromCharCode(64 + index); //this will return from A, and for number yield the index only
  }
}

const gen = generate();
console.log(gen.next().value); // A
console.log(gen.next().value); // B
console.log(gen.next().value); // C
Divek John
  • 623
  • 8
  • 16
-1

Why not just a simple join and split?

function seq(len, value)
{
    // create an array
    // join it using the value we want
    // split it
    return (new Array(len + 1)).join(value).split("");
}

seq(10, "a");
["a", "a", "a", "a", "a", "a", "a", "a", "a", "a"]

seq(5, 1);
["1", "1", "1", "1", "1"]
IMTheNachoMan
  • 5,343
  • 5
  • 40
  • 89
-1

Generating an integer sequence is something that should definitely be made more convenient in JavaScript. Here is a recursive function returns an integer array.

function intSequence(start, end, n = start, arr = []) {
  return n === end ? arr.concat(n)
    : intSequence(start, end, start < end ? n + 1 : n - 1, arr.concat(n));
}

$> intSequence(1, 1)
<- Array [ 1 ]

$> intSequence(1, 3)
<- Array(3) [ 1, 2, 3 ]

$> intSequence(3, -3)
<- Array(7) [ 3, 2, 1, 0, -1, -2, -3 ]
Zack
  • 294
  • 1
  • 10
  • I think it's safe to say that you should always try to avoid very long conditional operators (aka => x ? a : b ). Specially if you are doing recursion. I mean, is it really necessary to write this function in 2 lines? – Alexandre Dias Aug 05 '20 at 14:05