How can I create a two dimensional array in JavaScript?

后端 未结 30 4343
天涯浪人
天涯浪人 2020-11-21 05:25

I have been reading online and some places say it isn\'t possible, some say it is and then give an example and others refute the example, etc.

  1. How do I dec

相关标签:
30条回答
  • 2020-11-21 05:31

    Below one, creates a 5x5 matrix and fill them with null

    var md = [];
    for(var i=0; i<5; i++) {
        md.push(new Array(5).fill(null));
    }
    
    console.log(md);

    0 讨论(0)
  • 2020-11-21 05:33

    Use Array Comprehensions

    In JavaScript 1.7 and higher you can use array comprehensions to create two dimensional arrays. You can also filter and/or manipulate the entries while filling the array and don't have to use loops.

    var rows = [1, 2, 3];
    var cols = ["a", "b", "c", "d"];
    
    var grid = [ for (r of rows) [ for (c of cols) r+c ] ];
    
    /* 
             grid = [
                ["1a","1b","1c","1d"],
                ["2a","2b","2c","2d"],
                ["3a","3b","3c","3d"]
             ]
    */
    

    You can create any n x m array you want and fill it with a default value by calling

    var default = 0;  // your 2d array will be filled with this value
    var n_dim = 2;
    var m_dim = 7; 
    
    var arr = [ for (n of Array(n_dim)) [ for (m of Array(m_dim) default ]] 
    /* 
             arr = [
                [0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0],
             ]
    */
    

    More examples and documentation can be found here.

    Please note that this is not a standard feature yet.

    0 讨论(0)
  • 2020-11-21 05:34

    Performance

    Today 2020.02.05 I perform tests on MacOs HighSierra 10.13.6 on Chrome v79.0, Safari v13.0.4 and Firefox v72.0, for chosen solutions.

    Conclusions for non-initialised 2d array

    • esoteric solution {}/arr[[i,j]] (N) is fastest for big and small arrays and it looks like it is good choice for big sparse arrays
    • solutions based on for-[]/while (A,G) are fast and they are good choice for small arrays.
    • solutions for-[] (B,C) are fast and they are good choice for big arrays
    • solutions based on Array..map/from/fill (I,J,K,L,M) are quite slow for small arrays, and quite fast for big arrays
    • surprinsingly for-Array(n) (B,C) is much slower on safari than for-[] (A)
    • surprinsingly for-[] (A) for big array is slow on all browsers
    • solutions K is slow for small arrays for all browsers
    • solutions A,E,G are slow for big arrays for all browsers
    • solution M is slowest for all arrays on all browsers

    Conclusions for initialised 2d array

    • solutions based on for/while (A,B,C,D,E,G) are fastest/quite fast for small arrays on all browsers
    • solutions based on for (A,B,C,E) are fastest/quite fast for big arrays on all browsers
    • solutions based on Array..map/from/fill (I,J,K,L,M) are medium fast or slow for small arrays on all browsers
    • solutions F,G,H,I,J,K,L for big arrays are medium or fast on chrome and safari but slowest on firefox.
    • esoteric solution {}/arr[[i,j]] (N) is slowest for small and big arrays on all browsers

    Details

    Test for solutions which not fill (initialise) output array

    We test speed of solutions for

    • small arrays (12 elements) - you can perform tests on your machine HERE
    • big arrays (1 million elements) arrays - you can perform tests on your machine HERE

    function A(r) {
      var arr = [];
      for (var i = 0; i < r; i++) arr[i] = [];
      return arr;
    }
    
    function B(r, c) {
      var arr = new Array(r);
      for (var i = 0; i < arr.length; i++) arr[i] = new Array(c);
      return arr;
    }
    
    function C(r, c) {
      var arr = Array(r);
      for (var i = 0; i < arr.length; i++) arr[i] = Array(c);
      return arr;
    }
    
    function D(r, c) {
      // strange, but works
      var arr = [];
      for (var i = 0; i < r; i++) {
        arr.push([]);
        arr[i].push(Array(c));
      }
      return arr;
    }
    
    function E(r, c) {
      let array = [[]];
      for (var x = 0; x < c; x++) {
        array[x] = [];
        for (var y = 0; y < r; y++) array[x][y] = [0];
      }
      return array;
    }
    
    function F(r, c) {
      var makeArray = function(dims, arr) {
        if (dims[1] === undefined) {
          return Array(dims[0]);
        }
    
        arr = Array(dims[0]);
    
        for (var i = 0; i < dims[0]; i++) {
          arr[i] = Array(dims[1]);
          arr[i] = makeArray(dims.slice(1), arr[i]);
        }
    
        return arr;
      }
      return makeArray([r, c]);
    }
    
    function G(r) {
      var a = [];
      while (a.push([]) < r);
      return a;
    }
    
    function H(r,c) {
      function createArray(length) {
        var arr = new Array(length || 0),
            i = length;
    
        if (arguments.length > 1) {
            var args = Array.prototype.slice.call(arguments, 1);
            while(i--) arr[length-1 - i] = createArray.apply(this, args);
        }
    
        return arr;
      }
      return createArray(r,c);
    }
    
    function I(r, c) {
      return [...Array(r)].map(x => Array(c));
    }
    
    function J(r, c) {
      return Array(r).fill(0).map(() => Array(c));
    }
    
    function K(r, c) {
      return Array.from(Array(r), () => Array(c));
    }
    
    function L(r, c) {
      return Array.from({length: r}).map(e => Array(c));
    }
    
    function M(r, c) {
      return Array.from({length: r}, () => Array.from({length: c}, () => {}));
    }
    
    function N(r, c) {
      return {}
    }
    
    
    
    // -----------------------------------------------
    // SHOW
    // -----------------------------------------------
    
    log = (t, f) => {
      let A = f(3, 4); // create array with 3 rows and 4 columns
      A[1][2] = 6 // 2-nd row 3nd column set to 6
      console.log(`${t}[1][2]: ${A[1][2]}, full: ${JSON.stringify(A).replace(/null/g,'x')}`);
    }
    
    log2 = (t, f) => {
      let A = f(3, 4); // create array with 3 rows and 4 columns
      A[[1,2]] = 6 // 2-nd row 3nd column set to 6
      console.log(`${t}[1][2]: ${A[[1,2]]}, full: ${JSON.stringify(A).replace(/null/g,'x')}`);
    }
    
    log('A', A);
    log('B', B);
    log('C', C);
    log('D', D);
    log('E', E);
    log('F', F);
    log('G', G);
    log('H', H);
    log('I', I);
    log('J', J);
    log('K', K);
    log('L', L);
    log('M', M);
    log2('N', N);
    This is presentation of solutions - not benchmark

    Test for solutions which fill (initialise) output array

    We test speed of solutions for

    • small arrays (12 elements) - you can perform tests on your machine HERE
    • big arrays (1 million elements) arrays - you can perform tests on your machine HERE

    function A(r, c, def) {
      var arr = [];
      for (var i = 0; i < r; i++) arr[i] = Array(c).fill(def);
      return arr;
    }
    
    function B(r, c, def) {
      var arr = new Array(r);
      for (var i = 0; i < arr.length; i++) arr[i] = new Array(c).fill(def);
      return arr;
    }
    
    function C(r, c, def) {
      var arr = Array(r);
      for (var i = 0; i < arr.length; i++) arr[i] = Array(c).fill(def);
      return arr;
    }
    
    function D(r, c, def) {
      // strange, but works
      var arr = [];
      for (var i = 0; i < r; i++) {
        arr.push([]);
        arr[i].push(Array(c));
      }
      for (var i = 0; i < r; i++) for (var j = 0; j < c; j++) arr[i][j]=def
      return arr;
    }
    
    function E(r, c, def) {
      let array = [[]];
      for (var x = 0; x < c; x++) {
        array[x] = [];
        for (var y = 0; y < r; y++) array[x][y] = def;
      }
      return array;
    }
    
    function F(r, c, def) {
      var makeArray = function(dims, arr) {
        if (dims[1] === undefined) {
          return Array(dims[0]).fill(def);
        }
    
        arr = Array(dims[0]);
    
        for (var i = 0; i < dims[0]; i++) {
          arr[i] = Array(dims[1]);
          arr[i] = makeArray(dims.slice(1), arr[i]);
        }
    
        return arr;
      }
      return makeArray([r, c]);
    }
    
    function G(r, c, def) {
      var a = [];
      while (a.push(Array(c).fill(def)) < r);
      return a;
    }
    
    function H(r,c, def) {
      function createArray(length) {
        var arr = new Array(length || 0),
            i = length;
    
        if (arguments.length > 1) {
            var args = Array.prototype.slice.call(arguments, 1);
            while(i--) arr[length-1 - i] = createArray.apply(this, args).fill(def);
        }
    
        return arr;
      }
      return createArray(r,c);
    }
    
    function I(r, c, def) {
      return [...Array(r)].map(x => Array(c).fill(def));
    }
    
    function J(r, c, def) {
      return Array(r).fill(0).map(() => Array(c).fill(def));
    }
    
    function K(r, c, def) {
      return Array.from(Array(r), () => Array(c).fill(def));
    }
    
    function L(r, c, def) {
      return Array.from({length: r}).map(e => Array(c).fill(def));
    }
    
    function M(r, c, def) {
      return Array.from({length: r}, () => Array.from({length: c}, () => def));
    }
    
    function N(r, c, def) {
      let arr={};
      for (var i = 0; i < r; i++) for (var j = 0; j < c; j++) arr[[i,j]]=def;
      return arr;
    }
    
    
    
    // -----------------------------------------------
    // SHOW
    // -----------------------------------------------
    
    log = (t, f) => {
      let A = f(1000,1000,7); // create array with 1000 rows and 1000 columns, 
                              // each array cell initilised by 7
      A[800][900] = 5         // 800nd row and 901nd column set to 5
      console.log(`${t}[1][2]: ${A[1][2]}, ${t}[800][901]: ${A[800][900]}`);
    }
    
    log2 = (t, f) => {
      let A = f(1000,1000,7); // create array with 1000 rows and 1000 columns, 
                              // each array cell initilised by 7
      A[[800,900]] = 5            // 800nd row 900nd column set to 5
      console.log(`${t}[1][2]: ${A[[1,2]]}, ${t}[800][900]: ${A[[800,900]]}`);
    }
    
    log('A', A);
    log('B', B);
    log('C', C);
    log('D', D);
    log('E', E);
    log('F', F);
    log('G', G);
    log('H', H);
    log('I', I);
    log('J', J);
    log('K', K);
    log('L', L);
    log('M', M);
    log2('N', N);
    This is presentation of solutions - not benchmark

    0 讨论(0)
  • 2020-11-21 05:35

    To create a non-sparse "2D" array (x,y) with all indices addressable and values set to null:

    let 2Darray = new Array(x).fill(null).map(item =>(new Array(y).fill(null))) 
    

    bonus "3D" Array (x,y,z)

    let 3Darray = new Array(x).fill(null).map(item=>(new Array(y).fill(null)).map(item=>Array(z).fill(null)))
    

    Variations and corrections on this have been mentioned in comments and at various points in response to this question but not as an actual answer so I am adding it here.

    It should be noted that (similar to most other answers) this has O(x*y) time complexity so it probably not suitable for very large arrays.

    0 讨论(0)
  • 2020-11-21 05:35

    There is another solution, that does not force you to pre-define the size of the 2d array, and that is very concise.

    var table = {}
    table[[1,2]] = 3 // Notice the double [[ and ]]
    console.log(table[[1,2]]) // -> 3

    This works because, [1,2] is transformed into a string, that is used as a string key for the table object.

    0 讨论(0)
  • 2020-11-21 05:36

    The easiest way:

    var arr  = [];
    
    var arr1 = ['00','01'];
    var arr2 = ['10','11'];
    var arr3 = ['20','21'];
    
    arr.push(arr1);
    arr.push(arr2);
    arr.push(arr3);
    
    alert(arr[0][1]); // '01'
    alert(arr[1][1]); // '11'
    alert(arr[2][0]); // '20'
    
    0 讨论(0)
提交回复
热议问题