簡體   English   中英

如何在 JavaScript 中創建一個二維數組?

[英]How can I create a two dimensional array in JavaScript?

在網上看有的說不可能,有的說可以然后舉個例子,還有的反駁例子等等。

  1. 如何在 JavaScript 中聲明一個二維數組? (假設這是可能的)

  2. 我將如何訪問其成員? myArray[0][1]myArray[0,1] ?)

 var items = [ [1, 2], [3, 4], [5, 6] ]; console.log(items[0][0]); // 1 console.log(items[0][1]); // 2 console.log(items[1][0]); // 3 console.log(items[1][1]); // 4 console.log(items);

您只需將數組中的每個項目設為一個數組。

 var x = new Array(10); for (var i = 0; i < x.length; i++) { x[i] = new Array(3); } console.log(x);

與 activa 的回答類似,這里有一個創建 n 維數組的函數:

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;
}

createArray();     // [] or new Array()

createArray(2);    // new Array(2)

createArray(3, 2); // [new Array(2),
                   //  new Array(2),
                   //  new Array(2)]

如何創建一個空的二維數組(一行)

Array.from(Array(2), () => new Array(4))

2和4分別是第一維和第二維。

我們正在使用Array.from ,它可以采用類似數組的參數和每個元素的可選映射。

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

 var arr = Array.from(Array(2), () => new Array(4)); arr[0][0] = 'foo'; console.info(arr);

可以使用相同的技巧來創建包含 1...N 的 JavaScript 數組


或者(但效率低下12%, n = 10,000

Array(2).fill(null).map(() => Array(4))

性能下降是因為我們必須初始化第一個維度值才能運行.map 請記住, Array不會分配位置,直到您通過.fill或直接賦值對其進行.fill

 var arr = Array(2).fill(null).map(() => Array(4)); arr[0][0] = 'foo'; console.info(arr);


跟進

這是一種看似正確但存在問題的方法

 Array(2).fill(Array(4)); // BAD! Rows are copied by reference

雖然它確實返回了顯然需要的二維數組( [ [ <4 empty items> ], [ <4 empty items> ] ] ),但有一個問題:第一維數組已通過引用復制。 這意味着arr[0][0] = 'foo'實際上會更改兩行而不是一行。

 var arr = Array(2).fill(Array(4)); arr[0][0] = 'foo'; console.info(arr); console.info(arr[0][0], arr[1][0]);

Javascript 只有一維數組,但正如其他人指出的那樣,您可以構建數組數組。

以下函數可用於構造固定維度的二維數組:

function Create2DArray(rows) {
  var arr = [];

  for (var i=0;i<rows;i++) {
     arr[i] = [];
  }

  return arr;
}

列數並不重要,因為在使用數組之前不需要指定數組的大小。

然后你可以打電話:

var arr = Create2DArray(100);

arr[50][2] = 5;
arr[70][5] = 7454;
// ...

最簡單的方法:

var myArray = [[]];

有人說這是不可能的原因是因為二維數組實際上只是一個數組數組。 此處的其他注釋提供了在 JavaScript 中創建二維數組的完全有效的方法,但最純粹的觀點是您有一個一維對象數組,這些對象中的每一個都是由兩個元素組成的一維數組。

所以,這就是觀點沖突的原因。

很少有人展示 push 的用法:
為了帶來新的東西,我將向您展示如何使用某個值初始化矩陣,例如:0 或空字符串“”。
提醒一下,如果您有一個 10 個元素的數組,在 javascript 中,最后一個索引將為 9!

function matrix( rows, cols, defaultValue){

  var arr = [];

  // Creates all lines:
  for(var i=0; i < rows; i++){

      // Creates an empty line
      arr.push([]);

      // Adds cols to the empty line:
      arr[i].push( new Array(cols));

      for(var j=0; j < cols; j++){
        // Initializes:
        arr[i][j] = defaultValue;
      }
  }

return arr;
}

用法示例:

x = matrix( 2 , 3,''); // 2 lines, 3 cols filled with empty string
y = matrix( 10, 5, 0);// 10 lines, 5 cols filled with 0

兩線:

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

它將生成一個長度為 10 的數組 a,其中填充了數組。 (push 向數組中添加一個元素並返回新的長度)

最明智的答案似乎是

 var nrows = ~~(Math.random() * 10); var ncols = ~~(Math.random() * 10); console.log(`rows:${nrows}`); console.log(`cols:${ncols}`); var matrix = new Array(nrows).fill(0).map(row => new Array(ncols).fill(0)); console.log(matrix);


請注意,我們不能直接填充行,因為填充使用淺拷貝構造函數,因此所有行將共享相同的內存......這是演示如何共享每一行的示例(取自其他答案):

// DON'T do this: each row in arr, is shared
var arr = Array(2).fill(Array(4));
arr[0][0] = 'foo'; // also modifies arr[1][0]
console.info(arr);

最簡單的方法:

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'

這就是我取得的成就:

 var appVar = [[]]; appVar[0][4] = "bineesh"; appVar[0][5] = "kumar"; console.log(appVar[0][4] + appVar[0][5]); console.log(appVar);

這拼寫了我 bineeshkumar

二維數組的創建方式與一維數組相同。 你可以像array[0][1]一樣訪問它們。

var arr = [1, 2, [3, 4], 5];

alert (arr[2][1]); //alerts "4"

表現

今天 2020.02.05 我在 Chrome v79.0、Safari v13.0.4 和 Firefox v72.0 上對 MacOs HighSierra 10.13.6 進行測試,以獲取選定的解決方案。

非初始化二維數組的結論

  • 深奧的解決方案{}/arr[[i,j]] (N) 對於大數組和小數組來說是最快的,它看起來是大稀疏數組的不錯選擇
  • 基於for-[]/while (A,G) 的解決方案速度很快,是小數組的不錯選擇。
  • - for-[] (B,C) 的解決方案很快,它們是大數組的不錯選擇
  • 基於Array..map/from/fill (I,J,K,L,M) 的解決方案對於小數組來說非常慢,對於大數組來說非常快
  • 令人驚訝的是for-Array(n) (B,C) 在 safari 上比for-[] (A) 慢得多
  • 令人驚訝的是,大數組的for-[] (A) 在所有瀏覽器上都很慢
  • 解決方案 K 對於所有瀏覽器的小數組都很慢
  • 對於所有瀏覽器的大數組,解決方案 A、E、G 都很慢
  • 對於所有瀏覽器上的所有數組,解決方案 M 是最慢的

在此處輸入圖片說明

初始化二維數組的結論

  • 基於for/while (A,B,C,D,E,G) 的解決方案for/while所有瀏覽器上的小數組來說是最快/相當快的
  • for所有瀏覽器上的大數組,基於for (A,B,C,E) 的解決方案是最快/相當快的
  • 基於Array..map/from/fill (I,J,K,L,M) 的解決方案對於所有瀏覽器上的小數組來說是中等快或慢
  • 大陣列的解決方案 F、G、H、I、J、K、L 在 chrome 和 safari 上中等或快,但在 firefox 上最慢。
  • 深奧的解決方案{}/arr[[i,j]] (N) 對於所有瀏覽器上的小數組和大數組都是最慢的

在此處輸入圖片說明

細節

測試未填充(初始化)輸出數組的解決方案

我們測試解決方案的速度

  • 小陣列(12 個元素) - 您可以在您的機器上執行測試這里
  • 大數組(100 萬個元素)數組 - 您可以在您的機器上執行測試這里

 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

測試填充(初始化)輸出數組的解決方案

我們測試解決方案的速度

  • 小陣列(12 個元素) - 您可以在您的機器上執行測試這里
  • 大數組(100 萬個元素)數組 - 您可以在您的機器上執行測試這里

 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

在此處輸入圖片說明

我不確定是否有人回答過這個問題,但我發現這對我很有效 -

var array = [[,],[,]]

例如:

var a = [[1,2],[3,4]]

例如,對於二維數組。

要創建一個非稀疏的“2D”數組 (x,y),其中所有索引均可尋址且值設置為 null:

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

獎金“3D”陣列(x,y,z)

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

對此問題的評論和不同點都提到了對此的變化和更正,但不是作為實際答案,所以我在這里添加它。

應該注意的是(類似於大多數其他答案)這具有 O(x*y) 時間復雜度,因此它可能不適合非常大的數組。

要在 javaScript 中創建 2D 數組,我們可以先創建一個 Array,然后添加 Arrays 作為它的元素。 此方法將返回具有給定行數和列數的二維數組。

function Create2DArray(rows,columns) {
   var x = new Array(rows);
   for (var i = 0; i < rows; i++) {
       x[i] = new Array(columns);
   }
   return x;
}

要創建一個數組,請使用此方法,如下所示。

var array = Create2DArray(10,20);

對於一個班輪愛好者Array.from()

// creates 8x8 array filed with "0"    
const arr2d = Array.from({ length: 8 }, () => Array.from({ length: 8 }, () => "0"))

另一個(來自 dmitry_romanov 的評論)使用Array().fill()

// creates 8x8 array filed with "0"    
const arr2d = Array(8).fill(0).map(() => Array(8).fill("0"))

使用 ES6+ 擴展運算符(受 InspiredJW回答的“啟發”:))

// same as above just a little shorter
const arr2d = [...Array(8)].map(() => Array(8).fill("0"))

要創建一個 4x6 數組,只需執行以下操作

const x = [...new Array(6)].map(elem => new Array(4))

從一個空數組開始,而不是填充 w 個隨機值通常是一個好習慣。 (您通常在一維中將數組聲明為const x = [] ,因此最好在二維中將 w 設為空。)

Array(m).fill(v).map(() => Array(n).fill(v))

您可以創建一個 2 維數組mxn ,初始值m並且n可以是任何數字v可以是任何值stringnumberundefined

一種方法可以是var a = [m][n]

使用數組推導式

在 JavaScript 1.7 及更高版本中,您可以使用數組推導式來創建二維數組。 您還可以在填充數組時過濾和/或操作條目,而不必使用循環。

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"]
         ]
*/

您可以創建您想要的任何nxm數組,並通過調用使用默認值填充它

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],
         ]
*/

可以在此處找到更多示例和文檔。

請注意,這還不是標准功能

我發現下面是最簡單的方法:

 var array1 = [[]]; array1[0][100] = 5; alert(array1[0][100]); alert(array1.length); alert(array1[0].length);

我的方法與@Bineesh 的答案非常相似,但采用了更通用的方法。

您可以按如下方式聲明雙數組:

var myDoubleArray = [[]];

並以以下方式存儲和訪問內容:

var testArray1 = [9,8]
var testArray2 = [3,5,7,9,10]
var testArray3 = {"test":123}
var index = 0;

myDoubleArray[index++] = testArray1;
myDoubleArray[index++] = testArray2;
myDoubleArray[index++] = testArray3;

console.log(myDoubleArray[0],myDoubleArray[1][3], myDoubleArray[2]['test'],) 

這將打印預期的輸出

[ 9, 8 ] 9 123

只有在運行時才知道數組的大小,然后可以使用以下方法創建動態二維數組

 var num = '123456'; var row = 3; // Known at run time var col = 2; // Known at run time var i = 0; var array2D = [[]]; for(var r = 0; r < row; ++r) { array2D[r] = []; for(var c = 0; c < col; ++c) { array2D[r][c] = num[i++]; } } console.log(array2D); // [[ '1', '2' ], // [ '3', '4' ], // [ '5', '6' ]] console.log(array2D[2][1]); // 6

Javascript 不支持二維數組,而是我們將一個數組存儲在另一個數組中,並根據要訪問該數組的位置從該數組中獲取數據。 記得在陣列記數開始。

代碼示例:

/* Two dimensional array that's 5 x 5 

       C0 C1 C2 C3 C4 
    R0[1][1][1][1][1] 
    R1[1][1][1][1][1] 
    R2[1][1][1][1][1] 
    R3[1][1][1][1][1] 
    R4[1][1][1][1][1] 
*/

var row0 = [1,1,1,1,1],
    row1 = [1,1,1,1,1],
    row2 = [1,1,1,1,1],
    row3 = [1,1,1,1,1],
    row4 = [1,1,1,1,1];

var table = [row0,row1,row2,row3,row4];
console.log(table[0][0]); // Get the first item in the array

 var playList = [ ['I Did It My Way', 'Frank Sinatra'], ['Respect', 'Aretha Franklin'], ['Imagine', 'John Lennon'], ['Born to Run', 'Bruce Springsteen'], ['Louie Louie', 'The Kingsmen'], ['Maybellene', 'Chuck Berry'] ]; function print(message) { document.write(message); } function printSongs( songs ) { var listHTML; listHTML = '<ol>'; for ( var i = 0; i < songs.length; i += 1) { listHTML += '<li>' + songs[i][0] + ' by ' + songs[i][1] + '</li>'; } listHTML += '</ol>'; print(listHTML); } printSongs(playList);

ES6+、ES2015+ 可以用更簡單的方式做到這一點


創建 3 x 2 數組,填充為 true

[...Array(3)].map(item => Array(2).fill(true))

我必須制作一個靈活的數組函數來根據需要向其中添加“記錄”,並能夠更新它們並在將其發送到數據庫進行進一步處理之前進行任何需要的計算。 這是代碼,希望它有幫助:)。

function Add2List(clmn1, clmn2, clmn3) {
    aColumns.push(clmn1,clmn2,clmn3); // Creates array with "record"
    aLine.splice(aPos, 0,aColumns);  // Inserts new "record" at position aPos in main array
    aColumns = [];    // Resets temporary array
    aPos++ // Increments position not to overlap previous "records"
}

隨意優化和/或指出任何錯誤:)

這是我發現的一種制作二維數組的快速方法。

function createArray(x, y) {
    return Array.apply(null, Array(x)).map(e => Array(y));
}

您也可以輕松地將此功能轉換為 ES5 功能。

function createArray(x, y) {
    return Array.apply(null, Array(x)).map(function(e) {
        return Array(y);
    });
}

為什么會這樣: new Array(n)構造函數創建一個原型為Array.prototype的對象,然后分配對象的length ,從而產生一個未填充的數組。 由於缺少實際成員,我們無法在其上運行Array.prototype.map函數。

但是,當您向構造函數提供多個參數時,例如執行Array(1, 2, 3, 4) ,構造函數將使用arguments對象來正確實例化和填充Array對象。

出於這個原因,我們可以使用Array.apply(null, Array(x)) ,因為apply函數會將參數傳播到構造函數中。 為了澄清Array.apply(null, Array(3)) ,執行Array.apply(null, Array(3))等效於執行Array(null, null, null)

現在我們已經創建了一個實際的填充數組,我們需要做的就是調用map並創建第二層 ( y )。

在下方,創建一個5x5矩陣並將其填充為null

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

一個用於創建填充為 0 的 am*n 二維數組的襯墊。

new Array(m).fill(new Array(n).fill(0));

我一直在網上閱讀,有些地方說這是不可能的,有些地方說是不可能,然后舉一個例子,另一些地方則反駁該例子,等等。

  1. 如何在JavaScript中聲明二維數組? (假設有可能)

  2. 我將如何訪問其成員? myArray[0][1]myArray[0,1]嗎?)

我發現此代碼對我有用:

var map = [
    []
];

mapWidth = 50;
mapHeight = 50;
fillEmptyMap(map, mapWidth, mapHeight);

...

function fillEmptyMap(array, width, height) {
    for (var x = 0; x < width; x++) {
        array[x] = [];
        for (var y = 0; y < height; y++) {

            array[x][y] = [0];
        }
    }
}

一個簡化的例子:

var blocks = [];

blocks[0] = [];

blocks[0][0] = 7;

我不喜歡使用.fill()的 ES6 解決方案。 有些可能會起作用,但是為了避免逐引用復制問題而使用的額外圈套使它們變得不直觀。

我建議的 ES6 方法是對外部和內部數組充分利用擴展運算符。 關於 IMO 的推理更容易。

[...Array(3)].map(() => [...Array(4)])

如果您需要設置初始值,那么您可以在內部數組創建時鏈接.map()

[...Array(3)].map(() => [...Array(4)].map(() => 0))

最后,一個類型安全的 TypeScript util 函數:

export const createMultiDimensionalArray = <T>(
  n: number,
  m: number,
  initialVal?: T,
): T[][] => {
  const matrix = [...Array(n)].map(() => [...Array(m)]);
  return initialVal === undefined
    ? matrix
    : matrix.map(r => r.map(() => initialVal));
};

使用它的例子:

const a = createMultiDimensionalArray(1, 2);
a[1][2] = 3;     // Works

const b = createMultiDimensionalArray(2, 3, false);
b[1][2] = true;  // Works
b[1][2] = 3;     // Error: Type '3' is not assignable to type 'boolean'.

您可以分配一個行數組,其中每一行都是相同長度的數組。 或者,您可以分配帶有row * columns元素的一維數組,並定義將行/列坐標映射到元素索引的方法。

無論選擇哪種實現,如果將其包裝在一個對象中,都可以在原型中定義訪問器方法,以使API易於使用。

我修改了Matthew Crumley關於創建多維數組函數的答案。 我已經添加了要作為數組變量傳遞的數組的尺寸,並且將有另一個變量value ,它將用於設置多維數組中最后一個數組的元素的值。

/*
*   Function to create an n-dimensional array
*
*   @param array dimensions
*   @param any type value
*
*   @return array array
 */
function createArray(dimensions, value) {
    // Create new array
    var array = new Array(dimensions[0] || 0);
    var i = dimensions[0];

    // If dimensions array's length is bigger than 1
    // we start creating arrays in the array elements with recursions
    // to achieve multidimensional array
    if (dimensions.length > 1) {
        // Remove the first value from the array
        var args = Array.prototype.slice.call(dimensions, 1);
        // For each index in the created array create a new array with recursion
        while(i--) {
            array[dimensions[0]-1 - i] = createArray(args, value);
        }
    // If there is only one element left in the dimensions array
    // assign value to each of the new array's elements if value is set as param
    } else {
        if (typeof value !== 'undefined') {
            while(i--) {
                array[dimensions[0]-1 - i] = value;
            }
        }
    }

    return array;
}

createArray([]);              // [] or new Array()

createArray([2], 'empty');    // ['empty', 'empty']

createArray([3, 2], 0);       // [[0, 0],
                              //  [0, 0],
                              //  [0, 0]]
const arr = new Array(5).fill(new Array(5).fill(0));
console.log(arr);

創建多維數組的遞歸函數:

var makeArray = function (dims, arr) {          
    if (dims[1] === undefined) {
        return new Array(dims[0]);
    }

    arr = new Array(dims[0]);

    for (var i=0; i<dims[0]; i++) {
        arr[i] = new Array(dims[1]);
        arr[i] = makeArray(dims.slice(1), arr[i]);
    }

    return arr;
}

構建一個 2x3x4x2 的 4D 陣列:

var array = makeArray([2, 3, 4, 2]);    

您還可以創建一個函數來創建這樣的二維數組:

var myTable = [];

function createArray(myLength) {
    myTable = new Array(myLength);
    var cols, rows;
    for (cols = 0; cols < myLength; cols++) {
        myTable[cols] = new Array(myLength);
    }
}

您可以使用以下命令調用它,這將為您提供一個 10x10 的 2D 數組。

createArray(10);

您也可以使用此方法創建 3D 陣列。

nodejs + lodash版本:

var _ = require("lodash");
var result = _.chunk(['a', 'b', 'c', 'd', 'e', 'f'], 2);
console.log(result);
console.log(result[2][0]);

輸出:

[ [ 'a', 'b' ], [ 'c', 'd' ], [ 'e', 'f' ] ]
e
Array.from({length: rows}).map(e => new Array(columns));
 var items = [
      ["January 01", 42.5],
      ["February 01",  44.3],
      ["March 01",  28.7],
      ["April 01",  44.3],
      ["May 01",  22.9],
      ["June 01",  54.4],
      ["July 01",  69.3],
      ["August 01",  19.1],
      ["September 01",  82.5],
      ["October 01",  53.2],
      ["November 01",  75.9],
      ["December 01",  58.7]

    ];
  alert(items[1][0]); // February 01
  alert(items[5][1]); // 54.4

以下示例定義了一個名為活動的二維數組:

    let activities = [
        ['Work', 9],
        ['Eat', 1],
        ['Commute', 2],
        ['Play Game', 1],
        ['Sleep', 7]
    ];

在活動數組中,第一個維度表示活動,第二個維度顯示每個活動每天花費的小時數。

要在控制台中顯示活動數組,請使用 console.table() 方法,如下所示:

console.table(activities);

下面說明了輸出:

 ┌─────────┬─────────────┬───┐ │ (index) │ 0 │ 1 │ ├─────────┼─────────────┼───┤ │ 0 │ 'Work' │ 9 │ │ 1 │ 'Eat' │ 1 │ │ 2 │ 'Commute' │ 2 │ │ 3 │ 'Play Game' │ 1 │ │ 4 │ 'Sleep' │ 7 │ └─────────┴─────────────┴───┘

請注意, (index)列用於指示內部數組索引的插圖。

要訪問多維數組的元素,首先使用方括號訪問返回內部數組的外部數組元素; 然后使用另一個方括號訪問內部數組的元素。

以下示例返回上述活動數組中第一個內部數組的第二個元素:

console.log(activities[0][1]); // 9

向 JavaScript 多維數組添加元素

您可以使用諸如push()splice()類的 Array 方法來操作多維數組的元素。

例如,要在多維數組的末尾添加一個新元素,請使用push()方法,如下所示:

activities.push(['Study',2]);
 ┌─────────┬─────────────┬───┐ │ (index) │ 0 │ 1 │ ├─────────┼─────────────┼───┤ │ 0 │ 'Work' │ 9 │ │ 1 │ 'Eat' │ 1 │ │ 2 │ 'Commute' │ 2 │ │ 3 │ 'Play Game' │ 1 │ │ 4 │ 'Sleep' │ 7 │ │ 5 │ 'Study' │ 2 │ └─────────┴─────────────┴───┘

要在數組中間插入元素,請使用splice()方法。 下面在活動數組的第二個位置插入一個元素:

activities.splice(1, 0, ['Programming', 2]);
 ┌─────────┬───────────────┬───┐ │ (index) │ 0 │ 1 │ ├─────────┼───────────────┼───┤ │ 0 │ 'Work' │ 9 │ │ 1 │ 'Programming' │ 2 │ │ 2 │ 'Eat' │ 1 │ │ 3 │ 'Commute' │ 2 │ │ 4 │ 'Play Game' │ 1 │ │ 5 │ 'Sleep' │ 7 │ │ 6 │ 'Study' │ 2 │ └─────────┴───────────────┴───┘

此示例計算在每個活動上花費的小時數的百分比,並將該百分比附加到內部數組。

activities.forEach(activity => {
    let percentage = ((activity[1] / 24) * 100).toFixed();
    activity[2] = percentage + '%';
});
 ┌─────────┬───────────────┬───┬───────┐ │ (index) │ 0 │ 1 │ 2 │ ├─────────┼───────────────┼───┼───────┤ │ 0 │ 'Work' │ 9 │ '38%' │ │ 1 │ 'Programming' │ 2 │ '8%' │ │ 2 │ 'Eat' │ 1 │ '4%' │ │ 3 │ 'Commute' │ 2 │ '8%' │ │ 4 │ 'Play Game' │ 1 │ '4%' │ │ 5 │ 'Sleep' │ 7 │ '29%' │ │ 6 │ 'Study' │ 2 │ '8%' │ └─────────┴───────────────┴───┴───────┘

從 JavaScript 多維數組中刪除元素

要從數組中刪除元素,請使用pop()splice()方法。

例如,以下語句刪除活動數組的最后一個元素:

activities.pop();
 ┌─────────┬───────────────┬───┬───────┐ │ (index) │ 0 │ 1 │ 2 │ ├─────────┼───────────────┼───┼───────┤ │ 0 │ 'Work' │ 9 │ '38%' │ │ 1 │ 'Programming' │ 2 │ '8%' │ │ 2 │ 'Eat' │ 1 │ '4%' │ │ 3 │ 'Commute' │ 2 │ '8%' │ │ 4 │ 'Play Game' │ 1 │ '4%' │ │ 5 │ 'Sleep' │ 7 │ '29%' │ └─────────┴───────────────┴───┴───────┘

同樣,您可以使用pop()方法從多維數組的內部數組中刪除元素。 以下示例從活動數組的內部數組中刪除百分比元素。

activities.forEach((activity) => {
    activity.pop(2);
});
 ┌─────────┬───────────────┬───┐ │ (index) │ 0 │ 1 │ ├─────────┼───────────────┼───┤ │ 0 │ 'Work' │ 9 │ │ 1 │ 'Programming' │ 2 │ │ 2 │ 'Eat' │ 1 │ │ 3 │ 'Commute' │ 2 │ │ 4 │ 'Play Game' │ 1 │ │ 5 │ 'Sleep' │ 7 │ └─────────┴───────────────┴───┘

迭代 JavaScript 多維數組的元素

要迭代多維數組,請使用嵌套的for循環,如下例所示。

// loop the outer array

for (let i = 0; i < activities.length; i++) {
    // get the size of the inner array
    var innerArrayLength = activities[i].length;
    // loop the inner array
    for (let j = 0; j < innerArrayLength; j++) {
        console.log('[' + i + ',' + j + '] = ' + activities[i][j]);
    }
}

第一個循環遍歷外部數組的元素,嵌套循環遍歷內部數組的元素。

下面顯示了控制台中腳本的輸出:

 [0,0] = Work [0,1] = 9 [1,0] = Eat [1,1] = 1 [2,0] = Commute [2,1] = 2 [3,0] = Play Game [3,1] = 1 [4,0] = Sleep [4,1] = 7 [5,0] = Study [5,1] = 2

或者您可以兩次使用forEach()方法:

activities.forEach((activity) => {
    activity.forEach((data) => {
        console.log(data);
    });
});
 Work 9 Eat 1 Commute 2 Play Game 1 Sleep 7 Study 2

使用全局對象 Array 並用數組填充項目:

let arr = new Array(5).fill([]);

或者如果已知長度的二維數組:

let arr = new Array(5).fill(new Array(2));

如果您在使用 google 圖表的 2D 數組,最好的方法是

var finalData = [];
[["key",value], ["2013-8-5", 13.5], ["2013-7-29",19.7]...]

不是有效的二維數組谷歌圖表

var _field = (function()
{
    var array = [];
    for(var y = 0; y != 3; y++) { array[y] = new Array(5); }
    return array;
})();

// var item = _field[2][4];

如果數組的大小未知會發生什么? 或者數組應該動態創建和填充? 對我有用的替代解決方案是使用帶有靜態二維數組變量的類,如果數組中不存在索引,它將啟動它:

function _a(x,y,val){
    // return depending on parameters
    switch(arguments.length){
        case 0: return _a.a;
        case 1: return _a.a[x];
        case 2: return _a.a[x][y];
    }

    // declare array if wasn't declared yet
    if(typeof _a.a[x] == 'undefined')
        _a.a[x] = [];

    _a.a[x][y] = val;
}
// declare static empty variable
_a.a = [];

語法將是:

_a(1,1,2); // populates [1][1] with value 2
_a(1,1);   // 2 or alternative syntax _a.a[1][1]
_a(1);     // [undefined × 1, 2]
_a.a;      // [undefined × 1, Array[2]]
_a.a.length

這里有一個很棒的存儲庫。

  • api : masfufa.js

  • 示例:masfufa.html

兩個例子足以理解這個庫:

示例 1:

   /*     | 1 , 2 , 3 |
    * MX= | 4 , 5 , 6 |     Dimensions= 3 x 3
    *     | 7 , 8 , 9 |
    */ 


  jsdk.getAPI('my');
  var A=[1, 2, 3, 4, 5, 6, 7, 8, 9];
  var MX=myAPI.getInstance('masfufa',{data:A,dim:'3x3'});

然后 :

MX.get[0][0]  // -> 1 (first)
MX.get[2][2] //  ->9 (last)

示例 2:

   /*      | 1 , 9 , 3 , 4 |
    * MXB= | 4 , 5 , 6 , 2 |     Dimensions= 2 x 4
    *   
    */ 

  var B=[1 , 9 , 3 , 4 , 4 , 5 , 6 , 2];
  var MXB=myAPI.getInstance('masfufa',{data:B,dim:'2x4'});

然后 :

MXB.get[0][0]  // -> 1 (first)
MXB.get[1][3] //  -> 2 (last)
MXB.get[1][2] //  -> 6 (before last)

一些評論中提到了這一點,但使用 Array.fill() 將有助於構建二維數組:

function create2dArr(x,y) {
    var arr = [];
    for(var i = 0; i < y; i++) {
        arr.push(Array(x).fill(0));
    }
    return arr; 
}

這將在返回的數組中產生一個長度為 x, y 次的數組。

這是我對多維數組的實現。

在這種方法中,我正在創建一個單維數組

我在Array對象中添加了一個原型函數multi ,可用於創建任何維度的 Array。

我還為Array對象添加了一個原型函數index ,可用於從多維索引中獲取線性數組中的索引。

創建數組

//Equivalent to arr[I][J][K]..[] in C
var arr = new Array().multi(I,J,K,..);

訪問任何索引處的數組值

//Equivalent in C arr[i][j][k];
var vaue = arr[arr.index(i,j,k)];

片段

 /* Storing array as single dimension and access using Array.index(i,j,k,...) */ Array.prototype.multi = function(){ this.multi_size = arguments; this.multi_len = 1 for(key in arguments) this.multi_len *= arguments[key]; for(var i=0;i<this.multi_len;i++) this.push(0); return this; } Array.prototype.index = function(){ var _size = this.multi_len; var temp = 1; var index = 0; for(key in arguments) { temp*=this.multi_size[key]; index+=(arguments[key]*(_size/temp)) } return index; } // Now you can use the multi dimension array // A 3x3 2D Matrix var arr2d = new Array().multi(3,3); // A 2D Array arr2d[arr2d.index(1,1,1)] = 5; console.log(arr2d[arr2d.index(1,1,1)]); // A 3x3x3 3D Matrix var arr3d = new Array().multi(3,3,3); // a 3D Array arr3d[arr3d.index(1,1,1)] = 5; console.log(arr3d[arr3d.index(1,1,1)]); // A 4x3x3 4D Matrix var arr4d = new Array().multi(4,3,3,3); // a 4D Array arr4d[arr4d.index(4,0,0,1)] = 5; console.log(arr4d[arr4d.index(4,0,0,1)]);

如果你想要的只是一個 4x4 矩陣,看看DOMMatrix ,它很容易使用,我可以說,

let m = new DOMMatrix(); 
// m.m11, m.m12, m.m13, m.m14, ..., m.m41, m.m42, m.m43, m.m44

最初由於不同原因帶來,它在 node.js 上不可用,並且僅限於 4x4。

你也可以考慮使用自動激活對象而不是 JS 的數組,看看我的答案here但也帶到這里以獲得更多說服力:

var tree = () => new Proxy({}, { get: (target, name) => name in target ? target[name] : target[name] = tree() });

var t = tree();
t[0][2][3] = 4;
console.log(t[0][2][3]);

它使用新的 JS 並且在您迭代它時行為不正確,所以要小心它。

如果您需要一個靈活的多維數組生成器,也可以看看這個

為 Java Script 創建 n 維矩陣數組,填充初始默認值 0。

function arr (arg, def = 0){
      if (arg.length > 2){
        return Array(arg[0]).fill().map(()=>arr(arg.slice(1)));
      } else {
        return Array(arg[0]).fill().map(()=>Array(arg[1]).fill(def));
      }
    }

// Simple Usage of 4 dimensions
var s = arr([3,8,4,6])

// Use null default value with 2 dimensions
var k = arr([5,6] , null)

我的解決方案不會是最好的,但只是提供我的解決方案來創建用戶定義的多維數組。

此函數接受行和列,

function createArray(row,column) {
let arr = [];

for(var i=0; i<row; i++){
    arr[i] = [Math.floor(Math.random() * (10))];

    for(var j=0;j<column;j++){
        arr[i][j]= [Math.floor(Math.random() * (20))];
    }
}

return arr;
}

var arrVal = createArray(4, 5);

console.log(arrVal);

這構造了任何維度的 arrays。

function makeArrayChildren(parent, firstDimension, ...dimensions) {
  for (let i = 0; i < parent.length; i++) {
    parent[i] = new Array(firstDimension);
    if (dimensions.length != 0) {
      makeArrayChildren(parent[i], ...dimensions);
    }
  }
}
function makeArray(firstDimension, ...dimensions) {
  if (firstDimension == undefined) {
    throw Exception("Too few dimensions");
  }
  let topArray = new Array(firstDimension);
  if (dimensions.length != 0) makeArrayChildren(topArray, ...dimensions);
  return topArray;
}

這是我想做的另外兩個函數,我可以將其用作完整性檢查:一個 for each 對多維數組中的所有最低級別的項目執行,一個 fill 方法。

Array.prototype.dimensionalFill = function (value) {
  for (let i = 0; i < this.length; i++) {
    const elem = this[i];
    if (elem instanceof Array) {
      elem.dimensionalFill(value);
    } else {
      this[i] = value;
    }
  }
};
/*Unlike forEach, this also loops over undefined values. */
Array.prototype.dimensionalForEach = function (callableFunc, thisArg) {
  if (thisArg != undefined) {
    return this.dimensionalForEach(callableFunc.bind(thisArg));
  }
  for (let i = 0; i < this.length; i++) {
    const elem = this[i];
    if (elem instanceof Array) {
      elem.dimensionalForEach(callableFunc);
    } else {
      callableFunc(elem, i, this);
    }
  }
};

這是一個很好的小健全性檢查,它使用了所有的功能。 所以至少,它不可能是完全錯誤的。

let arr = makeArray(10, 10, 5, 4);
arr.dimensionalFill(2);
let sum = 0;
arr.dimensionalForEach((elem) => {
  sum += elem;
});
console.log(`sum: ${sum} === ${10 * 10 * 5 * 4 * 2}`);

值得一提的是,在這一點上,創建一個全新的結構會是一種更好的做法,但這很有趣。

這不是真正的答案,但也許根本不使用多維 arrays。 您可以輕松地做一個更大的一維數組並將索引器相乘並通過該值進行索引。 IMO 更清潔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM