20

is there a shorter, better way to generate 'n' length 2D array?

var a = (function(){ var i=9, arr=[]; while(i--) arr.push([]); return arr })(); a // [ [],[],[],[],[],[],[],[],[] ] 

** old-school short-way**:

var a = (function(a){ while(a.push([]) < 9); return a})([]); 

UPDATE - Using ES2015

Array(5).fill().map(a=>[]); // will create 5 Arrays in an Array // or Array.from({length:5}, a=>[]) 

Emptying 2D array (saves memory rather)

function make2dArray(len){ var a = []; while(a.push([]) < len); return a; } function empty2dArray(arr){ for( var i = arr.length; i--; ) arr[i].length = 0; } // lets make a 2D array of 3 items var a = make2dArray(3); // lets populate it a bit a[2].push('demo'); console.log(a); // [[],[],["demo"]] // clear the array empty2dArray(a); console.log(a); // [[],[],[]] 
7
  • 1
    Only if you put it in a function: var a = make2D(9); ;) Commented Jun 27, 2011 at 15:28
  • I am using it for a web-worker which needs a 2D empty array each time it's initialized Commented Jun 27, 2011 at 15:38
  • I wonder if there is some fancy EC5 for this Commented Jun 27, 2011 at 15:38
  • Btw. shorter is not necessarily better (just wanted to point out the differences in the title and the question body ;)). Commented Jun 27, 2011 at 15:52
  • And you could make it even shorter by passing the array as parameter instead of declaring it: var a = (function(a){ while(a.push([]) < 9); return a})([]); Commented Jun 27, 2011 at 15:59

10 Answers 10

26

Another way:

for(var a = [];a.length < 10; a.push([])); // semicolon is mandatory here 

Yet another way:

var a = []; while(a.push([]) < 10); 

This works because .push() [docs] (specification) returns the new length of the array.


That said, this is the wrong way of "reducing code". Create a dedicated function with a meaningful name and use this one. Your code will be much more understandable:

function get2DArray(size) { size = size > 0 ? size : 0; var arr = []; while(size--) { arr.push([]); } return arr; } var a = get2DArray(9); 

Code is read much more often than written.

Sign up to request clarification or add additional context in comments.

4 Comments

@vsync: True, somehow I thought I need to compare against 10 to get 9 elements. But anyway I like 10 more :P ;)
I believe the code should be small, but very well documenter in development, and on production it's compressed anyway, so you gain better compression rate this way.
I didn't know that 'a.push([])' returns a number. this is new for me that push returns a number, this is very interesting.
@vsync: Just added it to my answer. Because it is defined like that ;)
8

Just discovered another ES6 way with one line expression:

Array.from({length: N}, () => []) 

Array.from(arrayLike[, mapFn[, thisArg]])

More detail about its implementation/polyfill ⇢ MDN Array.from()

Yet another neat solution with help of array spread syntax:

[...Array(N)].map(() => []) 

1 Comment

Note that this is not one function call bun N + 1 because you call once Array.from() and N times () => [] function for each iteration that happens inside Array.from.
3
Array(cardinality).fill(0).map(function(item) {return [];}); 

where cardinality is the number of items you are looking at. In this case it would be 9. This was suggested by one of my colleagues actually. This is neat, I think :) This is valid from ECMA V6. Documentation: Array::fill

3 Comments

If you are using ES6, then this should be: Array(5).fill(0).map(()=> [])
@vsync, True that. However, you can define the prototype function yourself and use it in ECMA 5 if you want. That's what, I did for the time-being
I use Babel in my build process, so it can transforms it to ES5 automatically
0
var a = []; for(var i=0;i<10;i++) { a[i] = []; } 

4 Comments

Please post the output of console.log(a);. I'm curious to see whether it is the same as the OP posted. Ok, just kidding. -1 this just sets the length but it does not initialize anything.
This just sets the length, the elements are still 'undefined'
this won't create n entries with an empty array. in fact console.log return just a [].
I'm not sure why this was downvoted... it returns an empty 2D array. The output of JSON.stringify(a) is "[[],[],[],[],[],[],[],[],[],[]]".
0

shorter way can be :

for(var i=9,a=[];i>=0;i--){ a.push([]) } 

1 Comment

this is exactly the SAME as mine..yes 'for' is less characters than 'while'..but still.
0
var a = []; var max_length = 10; for(var i = 0; i < max_length; ++i){ a[i] = []; } 

6 Comments

you might as well do for(var i=9, a=[]; i--;){... - it's better
@vsync, why is starting at nine better?
@vsync -- i added a max_length param.
why not? it's less code then starting with zero then adding inside the loop. it gives the same result
@vsync, not when you are using a[i] = [] -- aalways better to start at 0
|
0
for(var i=9,a=[];i>=0;i--){ a.push([]) } 

1 Comment

hmmm..I would prefer a way which is more obvious that this is an assignment to some var..like var 2d = ....
0

In ES6:

(m, n, initialElementValue) => Array(m).fill(Array(n).fill(initialElementValue)) 

1 Comment

This would not create copies and would use the same array. So for example changing arr[0][1] would cause arr[1][1] and arr[2][1] to change. But it can be done that way
0

var x = 3, y = 5, arr = Array(y).fill(); arr = arr.map(function(){return Array(x).fill(' ')}); console.log(arr);

1 Comment

You answer does not provide any new information which wasn't already mentioned years ago by others here..
0

best way to generate 2D array in js by ES6 by Array.from

function twodimension(input) { let index = 0, sqrt = Math.sqrt(input.length); return Array.from({ length: sqrt }, (nothing, i) => Array.from({ length: sqrt }, (nothingTwo, j) => input[index++])) } console.log(twodimension('abcdefghijklmnopqrstupwxy')) console.log(twodimension([1,2,3,4,5,6,7,8,9]))

function input(length, fill) { let getNums = length * length; let fillNums = 1 if (fill == 'minus') { return Array.from({ length: length }, (nothing, i) => Array.from({ length: length }, (nothingTwo, j) => getNums--)) } else if (fill == 'plus') { return Array.from({ length: length }, (nothing, i) => Array.from({ length: length }, (nothingTwo, j) => fillNums++)) } // you can dping snake ladders also with Array.from if (fill === 'snakes') { return Array.from({ length: length }, (_, one) => Array.from({ length: length }, (_, two) => getNums--) ).map((el, i) => i % 2 == 1 && length % 2 == 0 ? el.reverse() : i % 2 == 0 && length % 2 == 1 ? el.reverse() : el ); } } console.log(input(8, 'minus')) console.log(input(10, 'plus')) console.log(input(5, 'snakes'))

you do anything with Array.from, it is easy to use and fast, this is the new method in ES6 syntax

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.