ฉันจะสร้างอาร์เรย์สองมิติใน JavaScript ได้อย่างไร


1136

ฉันอ่านออนไลน์แล้วและบางแห่งบอกว่าเป็นไปไม่ได้บางคนบอกว่ามันเป็นแบบนั้นจากนั้นให้ยกตัวอย่างและคนอื่น ๆ ปฏิเสธตัวอย่างเป็นต้น

  1. ฉันจะประกาศอาร์เรย์ 2 มิติใน JavaScript ได้อย่างไร (สมมติว่าเป็นไปได้)

  2. ฉันจะเข้าถึงสมาชิกได้อย่างไร ( myArray[0][1]หรือmyArray[0,1]?)


21
สมมติว่ามีความหมายค่อนข้างค่อนข้างจะเป็นไปไม่ได้ในทางเทคนิคในการสร้างอาร์เรย์ 2d ในจาวาสคริปต์ แต่คุณสามารถสร้างอาร์เรย์ของอาร์เรย์ซึ่งมีค่าเท่ากัน
IJ Kennedy

10
FYI ... เมื่อคุณเติมอาร์เรย์ด้วยอาร์เรย์ที่มากขึ้นโดยใช้var arr2D = new Array(5).fill(new Array(3));แต่ละองค์ประกอบของ Array (5) จะชี้ไปที่ Array เดียวกัน (3) ดังนั้นวิธีที่ดีที่สุดคือการใช้ for for loop เพื่อเติมอาร์เรย์ย่อยแบบไดนามิก
Josh Stribling

51
a = Array(5).fill(0).map(x => Array(10).fill(0))
Longfei Wu

2
กล่าวอีกนัยหนึ่งfillไม่เรียกnew Array(3)แต่ละดัชนีของอาเรย์ที่ถูกกรอกเนื่องจากไม่ใช่นิพจน์แลมบ์ดาหรืออะไรเช่นความคิดเห็นของ Longfei Wu ด้านบนซึ่งในตอนแรกจะเติมอาเรย์ด้วย 0 แล้วใช้ฟังก์ชันแผนที่กับแลมบ์ดา เติมแต่ละองค์ประกอบด้วยอาร์เรย์ใหม่ ฟังก์ชั่นเติมเพียงแค่เติมอาร์เรย์ด้วยสิ่งที่คุณบอกมัน มันสมเหตุสมผลไหม สำหรับข้อมูลเพิ่มเติมเกี่ยวกับmapฟังก์ชั่นโปรดดูที่: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

2
@kalehmann นั่นใช้ได้: meta.stackoverflow.com/a/252017/2311074 If the new question is a better question or has better answers, then vote to close the old one as a duplicate of the new one.
อดัม

คำตอบ:


1231

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


32
มันจะเป็นการยากที่จะเริ่มต้นอาร์เรย์หลายมิติขนาดใหญ่ด้วยวิธีนี้ อย่างไรก็ตามฟังก์ชั่นนี้สามารถใช้ในการสร้างมิติหลายมิติที่ว่างเปล่าโดยมีมิติที่ระบุเป็นพารามิเตอร์
Anderson Green

2
@AndersonGreen มันเป็นสิ่งที่ดีที่คุณพูดถึงลิงค์สำหรับผู้ที่สนใจในการแก้ปัญหาอาร์เรย์หลาย D แต่คำถามและคำตอบของ Ballsacian1 นั้นเกี่ยวกับอาร์เรย์ "2D" ไม่ใช่อาเรย์ "multi-D"
evilReiko

คุณควรดำเนินการทั้งหมด ... เช่นการแจ้งเตือน (รายการ [0] [1]); // 2 ฯลฯ
Dois

1
@SashikaXP สิ่งนี้ไม่สามารถใช้ได้กับดัชนีแรกนอกเหนือจาก 0
Michael Franzl

1
คำถามคือวิธีการประกาศอาร์เรย์สองมิติ ฉันพบสิ่งใดและพบสิ่งนี้และทำตามคำตอบซึ่งไม่สามารถแยกแยะความแตกต่างระหว่างการประกาศและการเริ่มต้นได้ นอกจากนี้ยังมีการประกาศด้วยความยาวที่รู้จักหรือไม่ จำกัด ซึ่งไม่ได้กล่าวถึง
chris

444

คุณเพียง แต่ทำให้แต่ละรายการภายในอาร์เรย์เป็นอาร์เรย์

var x = new Array(10);

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

console.log(x);


6
พวกเขาสามารถใช้สิ่งต่าง ๆ เช่นสายสำหรับคีย์และค่าของพวกเขา myArray ['Book'] ['item1']?
Diego

42
@Diego ใช่ แต่นั่นไม่ใช่สิ่งที่มีไว้สำหรับอาร์เรย์ ควรใช้วัตถุเมื่อคีย์ของคุณเป็นสตริง
Matthew Crumley

10
ฉันชอบตัวอย่างนี้ดีกว่าคำตอบที่ยอมรับเพราะสามารถนำไปใช้กับอาร์เรย์ที่มีขนาดแบบไดนามิกเช่นnew Array(size)ที่ไหนsizeเป็นตัวแปร
Variadicism

1
ไม่ทำงาน - ข้อผิดพลาดในการมอบหมาย คำตอบนี้ได้อย่างไร 280 ชอบถ้ามันไร้ประโยชน์?
Gargo

1
มันใช้งานได้ดีขอบคุณ คุณสามารถดูตัวอย่าง Gargo jsfiddle.net/matasoy/oetw73sj
matasoy

198

คล้ายกับคำตอบของ 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)]

2
สิ่งนี้สามารถสร้างอาเรย์ 4 มิติได้หรือไม่?
trusktr

4
@trusktr: ใช่คุณสามารถสร้างมิติได้มากเท่าที่คุณต้องการ (ภายในข้อ จำกัด หน่วยความจำของคุณ) เพียงผ่านความยาวของสี่มิติ ตัวอย่างเช่นvar array = createArray(2, 3, 4, 5);.
Matthew Crumley

4
คำตอบที่ดีที่สุด! อย่างไรก็ตามฉันไม่แนะนำให้ใช้กับพารามิเตอร์ 0 หรือ 1 (ไร้ประโยชน์)
Apolo

2
@BritishDeveloper ใช่ นี่คืออาร์เรย์ 5D ที่มีความยาวแต่ละช่วงเวลา 5:[[[[[null,null],[null,null]],[[null,null],[null,null]]],[[[null,null],[null,null]],[[null,null],[null,null]]]],[[[[null,null],[null,null]],[[null,null],[null,null]]],[[[null,null],[null,null]],[[null,null],[null,null]]]]]
haykam

2
@haykam ขอโทษที่ต้องเสียเวลาของคุณ - ฉันถูกเหน็บแนม: /
BritishDeveloper

84

Javascript มีเพียงอาร์เรย์ 1 มิติเท่านั้น แต่คุณสามารถสร้างอาร์เรย์ของอาร์เรย์ได้ตามที่คนอื่น ๆ ชี้ให้เห็น

ฟังก์ชั่นต่อไปนี้สามารถใช้ในการสร้างอาร์เรย์ 2 มิติของมิติคงที่:

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;
// ...

ฉันต้องการสร้างอาร์เรย์ 2 มิติที่จะเป็นตัวแทนของการ์ด ซึ่งจะเป็นอาเรย์ 2 มิติที่เก็บค่าบัตรแล้วในชุดนั้น อะไรจะเป็นวิธีที่ง่ายที่สุดในการทำเช่นนั้น
Doug Hauf

1
ฟังก์ชั่น Create2DArray (แถว) {var arr = []; สำหรับ (var i = 0; i <rows; i ++) {arr [i] = []; } กลับ arr; } ฟังก์ชันพิมพ์ (สำรับ) {สำหรับ (t = 1; t <= 4; t ++) {สำหรับ (i = 1; i <= 13; i ++) {document.writeln (สำรับ [t] [i]); }}} fucntion fillDeck (d) {สำหรับ (t = 1; t <= 4; t ++) {myCardDeck [t] [1] = t; สำหรับ (i = 1; i <= 13; i ++) {myCardDeck [t] [i] = i; }}} function loadCardDeck () {var myCardDeck = Create2DArray (13); fillDeck (myCardDeck); พิมพ์ (myCardDeck); }
Doug Hauf

2
@Doug: จริง ๆ แล้วคุณต้องการอาร์เรย์หนึ่งมิติของวัตถุที่มี 2 คุณลักษณะ var deck = []; สำรับ [0] = {หน้า: 1, ชุด: 'H'};
TeasingDart

@DougHauf นั่นเป็นอาร์เรย์ 2D ขนาดเล็กใช่ไหม? : P: D
Mahi

78

วิธีที่ง่ายที่สุด:

var myArray = [[]];

29
ซึ่งเป็นอาร์เรย์ 2 มิติ
Maurizio In denmark

15
ใช่ระวังให้ดี การกำหนด myArray [0] [อะไรก็ตาม] นั้นใช้ได้ แต่ลองตั้ง myArray [1] [อะไรก็ตาม] และมันก็บ่นว่า myArray [1] นั้นไม่ได้กำหนดไว้
ฟิลิป

22
@Philip คุณต้องตั้งค่าmyArray[1]=[];ก่อนกำหนดmyArray[1][0]=5;
182764125216

4
โปรดระวังสิ่งนี้จะไม่ "สร้างอาร์เรย์ 1x1 ที่ว่างเปล่า" ตามที่ @AndersonGreen เขียน มันสร้างอาร์เรย์ "1x0" (เช่น 1 แถวที่มีอาร์เรย์ที่มี 0 คอลัมน์) และmyArray.length == 1 myArray[0].length == 0ซึ่งจะให้ผลลัพธ์ที่ไม่ถูกต้องหากคุณคัดลอกอาร์เรย์ "0x0" ที่ว่างเปล่าอย่างแท้จริง
JonBrave

3
@ 182764125216 นั่นเป็นความรู้ในวันนี้สำหรับฉัน ขอบคุณ :)
th3pirat3

76

วิธีสร้างอาร์เรย์สองมิติที่ว่างเปล่า (หนึ่งบรรทัด)

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

เคล็ดลับเดียวกันนี้สามารถใช้สร้างอาร์เรย์ JavaScript ที่มี 1 ... N


อีกทางหนึ่ง (แต่ไม่มีประสิทธิภาพมากกว่า 12% ด้วยn = 10,000)

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

การลดลงของประสิทธิภาพนั้นมาพร้อมกับความจริงที่ว่าเราต้องมีค่ามิติแรกที่เริ่มต้นเพื่อให้ทำงาน.mapได้ โปรดจำไว้ว่า Arrayจะไม่จัดสรรตำแหน่งจนกว่าคุณจะสั่งซื้อผ่าน.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]);


ฉันแนะนำสิ่งนี้:Array.from({length:5}, () => [])
vsync

อัตนัยนี่ แต่คำตอบนี้ (ครั้งแรกและครั้งที่สองภายใน) ดูเหมือนว่าสมดุลที่ดีที่สุดของการรวบรัดรวดเร็วและทันสมัย
เบรดี้ดาวลิ่ง

@zurfyx ความคิดใด ๆ หรือใครรู้ว่าทำไม webstorm บ่นเกี่ยวกับเรื่องนี้? ดูเหมือนว่า array.from เก็บค่าไว้เหมือนไม่ได้กำหนดและจากนั้นฉันไม่สามารถทำงานกับอาร์เรย์ที่สร้างขึ้นได้แม้ว่าข้อมูลโค้ดจะทำงานได้ดีที่นี่ใน stackoverflow
FaultyJuggler

46

เหตุผลที่บางคนบอกว่ามันเป็นไปไม่ได้เพราะอาเรย์สองมิติเป็นเพียงอาร์เรย์อาเรย์ ความคิดเห็นอื่น ๆ ที่นี่ให้วิธีการที่ถูกต้องสมบูรณ์ในการสร้างอาร์เรย์สองมิติใน JavaScript แต่มุมมองที่บริสุทธิ์ที่สุดคือคุณมีอาร์เรย์หนึ่งมิติของวัตถุแต่ละวัตถุเหล่านั้นจะเป็นอาร์เรย์มิติหนึ่งซึ่งประกอบด้วยสององค์ประกอบ

นั่นคือสาเหตุของมุมมองที่ขัดแย้งกัน


41
ไม่มันไม่ใช่. ในบางภาษาคุณสามารถมีอาร์เรย์หลายมิติstring[3,5] = "foo";ได้ เป็นวิธีที่ดีกว่าสำหรับบางสถานการณ์เนื่องจากแกน Y ไม่ใช่ลูกของแกน X
Rafael Soares

3
เมื่อถึงรหัสเครื่องพื้นฐานมิติทั้งหมด> 1 เป็นอาร์เรย์ของอาร์เรย์ไม่ว่าเราจะพูดถึงภาษาใด ควรคำนึงถึงเหตุผลในการเพิ่มประสิทธิภาพแคช ภาษาที่เหมาะสมสำหรับการคำนวณเชิงตัวเลขอย่างจริงจังจะช่วยให้คุณสามารถจัดโครงสร้างหน่วยความจำหลายมิติในหน่วยความจำเพื่อให้มิติที่ใช้มากที่สุดของคุณถูกจัดเก็บอย่างต่อเนื่อง Pumpon Numpy, Fortran และ C เข้ามาในใจ อันที่จริงมีกรณีเมื่อคุ้มค่าที่จะลดมิติเป็นหลายโครงสร้างด้วยเหตุผลนี้
โทมัสบราวน์

คอมพิวเตอร์ไม่มีความคิดเกี่ยวกับมิติ ที่อยู่หน่วยความจำมีเพียง 1 มิติเท่านั้น ทุกสิ่งทุกอย่างเป็นสัญลักษณ์การตกแต่งเพื่อประโยชน์ของโปรแกรมเมอร์
TeasingDart

3
@ThomasBrowne ไม่ตรง "อาร์เรย์ของอาร์เรย์" จำเป็นต้องใช้ที่เก็บข้อมูลบางอย่างสำหรับขนาดของอาร์เรย์ภายใน (อาจแตกต่างกัน) และตัวชี้อื่นกำลังทำการค้นหาตำแหน่งที่เก็บอาร์เรย์ภายใน ในอาเรย์หลายภาษาที่ "เหมาะสม" นั้นแตกต่างจากอาเรย์แบบขรุขระเนื่องจากเป็นโครงสร้างข้อมูลที่แตกต่างกัน (และส่วนที่สับสนคืออาร์เรย์ C มีหลายระดับแม้ว่าจะจัดทำดัชนีด้วยไวยากรณ์ [a] [b])
polkovnikov.ph

33

มีเพียงไม่กี่คนที่แสดงให้เห็นถึงการใช้งานของพุช:
เพื่อนำสิ่งใหม่ ๆ มาให้ฉันจะแสดงวิธีเริ่มต้นเมทริกซ์ด้วยค่าบางค่าตัวอย่างเช่น 0 หรือสตริงว่าง ""
เตือนว่าถ้าคุณมี 10 องค์ประกอบอาร์เรย์ในจาวาสคริปต์ดัชนีสุดท้ายจะเป็น 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

ฉันจะลบที่ผ่านมาfor(ซึ่งตั้งค่าเริ่มต้น) จากขั้นตอนและการเขียนของคุณm=matrix(3,4); m[1][2]=2; console.log(JSON.stringify(m));- และเราได้รับเมทริกซ์ strage มาก (ซ้อนกันมากเกินไป) - คุณสามารถซ่อมแซมในช่วงขั้นตอนสำหรับ defaultValue แต่ฉันคิดว่าคุณสามารถเขียนขั้นตอนการใช้งานปักที่ซ้อนกันน้อยก่อน การตั้งค่าเริ่มต้น
Kamil Kiełczewski

27

สองสายการบิน:

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

มันจะสร้างอาร์เรย์ a ของความยาว 10 ที่เต็มไปด้วยอาร์เรย์ (Push เพิ่มองค์ประกอบให้กับอาร์เรย์และส่งคืนความยาวใหม่)


13
หนึ่งซับ: for (var a=[]; a.push([])<10;);?
Bergi

@Bergi ตัวแปรจะยังคงถูกกำหนดไว้ในบรรทัดถัดไป .. ?
StinkyCat

1
@Statycat: ใช่นั่นเป็นวิธีการvarทำงาน มันเป็นขอบเขตหน้าที่เสมอ
Bergi

ฉันรู้ว่าดังนั้นหนึ่งซับของคุณจะไม่ได้ผลในกรณีนี้คุณไม่สามารถ "เข้าถึงสมาชิก" (การตรวจสอบคำถาม)
StinkyCat

1
domenukk และ @Bergi คุณทั้งคู่ถูกต้อง ฉันลองใช้แล้วและฉันสามารถเข้าถึงได้ในภายหลังสำหรับ ฉันขอโทษ! และขอขอบคุณนี่อาจเป็นบทเรียนสำหรับฉัน;)
StinkyCat

24

คำตอบ sanest ดูเหมือนจะเป็น

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

นี่ควรเป็นจุดสูงสุด ฉันทำสิ่งที่คล้ายกันโดยใช้Array.apply(null, Array(nrows))แต่นี่สวยงามกว่ามาก
dimiguel

เรื่องนี้ความคิดเห็นล่าสุดของฉัน ... Internet Explorer และ Opera fillไม่ได้รับการสนับสนุนจาก สิ่งนี้จะไม่ทำงานกับเบราว์เซอร์ส่วนใหญ่
dimiguel

@dimgl Fill สามารถเลียนแบบได้ในอินสแตนซ์นี้ด้วยแผนที่คงที่: Array(nrows).map(() => 0)หรือArray(nrows).map(function(){ return 0; });
Conor O'Brien

20

วิธีที่ง่ายที่สุด:

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'

18

นี่คือสิ่งที่ฉันทำได้:

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

เรื่องนี้สะกดฉัน bineeshkumar


2
โปรดสังเกตว่าคุณจะสามารถเข้าถึงดัชนี 0 ของอาร์เรย์หลักได้อย่างไร สิ่งนี้ไม่ได้มีประโยชน์เหมือนอย่างที่ช่วยให้คุณตั้งค่าเช่น appVar [5] [9] = 10; ... คุณจะได้รับ 'ไม่สามารถตั้งค่าคุณสมบัติ "9" จากที่ไม่ได้กำหนด' ด้วยสิ่งนี้
RaisinBranCrunch

แต่appVar[1][4] = "bineesh";ผิดวิธีแก้มันได้อย่างไร
Gank

16

อาร์เรย์สองมิติถูกสร้างขึ้นเช่นเดียวกับอาร์เรย์มิติเดียว array[0][1]และคุณสามารถเข้าถึงพวกเขาเช่น

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

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

14

ฉันไม่แน่ใจว่ามีใครตอบคำถามนี้ แต่ฉันพบว่าสิ่งนี้ใช้ได้กับฉันค่อนข้างดี -

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

เช่น:

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

สำหรับอาร์เรย์ 2 มิติเป็นต้น


ฉันจะทำสิ่งนี้แบบไดนามิกได้อย่างไร ฉันต้องการอาร์เรย์ภายในที่มีขนาดแตกต่างกัน
alap

3
คุณไม่ต้องการเครื่องหมายจุลภาคพิเศษvar array = [[],[]]เพียงพอ
Kaya Toast

13

ในการสร้างอาเรย์สองมิติใน javaScript เราสามารถสร้างอาเรย์ก่อนแล้วจึงเพิ่มอาร์เรย์ในรูปแบบของมัน วิธีนี้จะส่งคืนอาร์เรย์ 2 มิติพร้อมจำนวนแถวและคอลัมน์ที่กำหนด

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

เพื่อสร้าง Array ให้ใช้วิธีนี้ดังต่อไปนี้

var array = Create2DArray(10,20);

2
โปรดให้คุณเพิ่มข้อมูลอธิบายลงใน ansdwer ของคุณเพื่อแสดงว่ามันทำงานอย่างไรและทำไมมันถึงแก้ปัญหาได้ สิ่งนี้จะช่วยให้ผู้อื่นที่พบหน้านี้ในอนาคต
คนของเราใน Bananas

เมื่อใดที่คุณจะต้องใช้ Array ที่กำหนดค่าเริ่มต้นด้วย colums จำนวนหนึ่งใน Javascript คุณสามารถเข้าถึงองค์ประกอบที่ n ของอาร์เรย์ [] ได้เช่นกัน
domenukk

ฉันสังเกตเห็นว่าฟังก์ชั่นเริ่มต้นด้วยตัวพิมพ์ใหญ่ C ซึ่ง (ตามอนุสัญญาบางอย่าง) แนะนำว่ามันจะเป็นตัวสร้างฟังก์ชั่นและคุณจะใช้มันกับคำหลักใหม่ เล็กน้อยมากและอาจจะดื้อดึง แต่ฉันยังคงแนะนำคำที่ไม่ได้เป็นตัวพิมพ์ใหญ่
Hachi

12

ในการสร้างอาร์เรย์ "2D" แบบไม่กระจาย (x, y) ด้วยดัชนีทั้งหมดที่กำหนดแอดเดรสได้และตั้งค่าเป็นศูนย์:

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

Array "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) ดังนั้นจึงอาจไม่เหมาะสำหรับอาร์เรย์ขนาดใหญ่มาก


1
ระวังเพราะfillตั้งค่าเดียวกัน ถ้าเปลี่ยนnullเป็น `วัตถุมันจะเป็นวัตถุเดียวกันในทุกคอลัมน์
Stanislav Mayorov

@StanislavMayorov หากคุณต้องการตั้งค่าของแต่ละเซลล์เพียงใช้เล่ห์เหลี่ยมเดียวกัน:let 2Darray = new Array(x).fill(null).map(item =>(new Array(y).fill(null).map(cell =>(yourValueHere))))
haykam

10

ใช้ความเข้าใจของอาเรย์

ใน JavaScript 1.7 และสูงกว่าคุณสามารถใช้array comprehensionsเพื่อสร้างอาร์เรย์สองมิติ นอกจากนี้คุณยังสามารถกรองและ / หรือจัดการรายการในขณะที่เติมอาร์เรย์และไม่ต้องใช้ลูป

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

คุณสามารถสร้างn x mอาร์เรย์ที่คุณต้องการแล้วเติมค่าเริ่มต้นด้วยการโทร

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

สามารถดูตัวอย่างและเอกสารเพิ่มเติมได้ที่นี่ที่นี่

โปรดทราบว่านี้ไม่ได้เป็นคุณสมบัติมาตรฐานเลย


Google ตรวจสอบอย่างรวดเร็วที่นี่ ... yup ... forคำสั่งยังคงเป็นวง ...
Pimp Trizkit

1
เบราว์เซอร์ใดที่ไม่รองรับ - นี่ ?
Kamil Kiełczewski

10

สำหรับหนึ่งคนรักซับใน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"))

2
เราสามารถลบ0ในfill()ฟังก์ชั่นแรก:const arr2d = Array(8).fill().map(() => Array(8).fill("0"));
Jinsong Li

8

วิธีการของฉันคล้ายกับคำตอบ @Binesh แต่มีวิธีการทั่วไปที่มากกว่า

คุณสามารถประกาศ double array ดังนี้

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

7

ฉันพบด้านล่างเป็นวิธีที่ง่ายที่สุด:

var array1 = [[]];   
array1[0][100] = 5; 

alert(array1[0][100]);
alert(array1.length);
alert(array1[0].length);

array1[1][100] = 666;พ่นUncaught TypeError: Cannot set property '100' of undefined
Kamil Kiełczewski

@ KamilKiełczewskiคุณมีสิทธิที่มีลักษณะเช่นนี้เพียงเริ่มต้นสำหรับอาร์เรย์แรกของอาร์เรย์ที่สองก่อนที่จะทำคุณจะต้องทำเช่นนี้array1[1][100] = 666; array1[1] = [];
GMsoF

7

ประสิทธิภาพ

วันนี้ 2020.02.05 ฉันทำการทดสอบบน MacOs HighSierra 10.13.6 บน Chrome v79.0, Safari v13.0.4 และ Firefox v72.0 สำหรับโซลูชันที่เลือก

สรุปสำหรับอาเรย์ 2d ที่ไม่ได้กำหนดค่าเริ่มต้น

  • โซลูชันลึกลับ{}/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) ช้ากว่าซาฟารีมากกว่ามากfor-[](A)
  • แปลกใจfor-[](A) สำหรับอาร์เรย์ขนาดใหญ่ช้าในเบราว์เซอร์ทั้งหมด
  • โซลูชัน K ช้าสำหรับอาร์เรย์ขนาดเล็กสำหรับเบราว์เซอร์ทั้งหมด
  • โซลูชัน A, E, G ช้าสำหรับอาร์เรย์ขนาดใหญ่สำหรับเบราว์เซอร์ทั้งหมด
  • ทางออก M ช้าที่สุดสำหรับทุกอาร์เรย์ในเบราว์เซอร์ทั้งหมด

ป้อนคำอธิบายรูปภาพที่นี่

ข้อสรุปสำหรับอาร์เรย์ 2 มิติที่เริ่มต้น

  • โซลูชันที่ใช้for/while(A, B, C, D, E, G) นั้นเร็วที่สุด / ค่อนข้างเร็วสำหรับอาร์เรย์ขนาดเล็กในเบราว์เซอร์ทั้งหมด
  • โซลูชันที่ใช้for(A, B, C, E) นั้นเร็วที่สุด / ค่อนข้างเร็วสำหรับอาร์เรย์ขนาดใหญ่ในเบราว์เซอร์ทั้งหมด
  • โซลูชันที่อิงตามArray..map/from/fill(I, J, K, L, M) นั้นมีความเร็วปานกลางหรือช้าสำหรับอาร์เรย์ขนาดเล็กในเบราว์เซอร์ทั้งหมด
  • โซลูชัน F, G, H, I, J, K, L สำหรับอาร์เรย์ขนาดใหญ่มีขนาดปานกลางหรือเร็วบนโครเมียมและซาฟารี แต่ช้าที่สุดใน Firefox
  • โซลูชันลึกลับ{}/arr[[i,j]](N) ช้าที่สุดสำหรับอาร์เรย์ขนาดเล็กและขนาดใหญ่ในเบราว์เซอร์ทั้งหมด

ป้อนคำอธิบายรูปภาพที่นี่

รายละเอียด

ทดสอบหาแนวทางแก้ไขที่ไม่ได้กรอกข้อมูล (เริ่มต้น) อาร์เรย์

เราทดสอบความเร็วของโซลูชันสำหรับ

  • อาร์เรย์ขนาดเล็ก (12 องค์ประกอบ) - คุณสามารถทำการทดสอบบนเครื่องของคุณที่นี่
  • อาร์เรย์ขนาดใหญ่ (1 ล้านองค์ประกอบ) - คุณสามารถทำการทดสอบบนเครื่องของคุณได้ที่นี่

ทดสอบโซลูชันที่เติมเอาต์พุต (initialise) อาร์เรย์

เราทดสอบความเร็วของโซลูชันสำหรับ

  • อาร์เรย์ขนาดเล็ก (12 องค์ประกอบ) - คุณสามารถทำการทดสอบบนเครื่องของคุณที่นี่
  • อาร์เรย์ขนาดใหญ่ (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

6

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


6

ES6 +, ES2015 + สามารถทำได้ในวิธีที่ง่ายยิ่งขึ้น


การสร้างอาร์เรย์ 3 x 2 ที่เต็มไปด้วยความจริง

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

ฉันต้องสารภาพ ฉัน "ลูกบุญธรรม" คำตอบของคุณและเพิ่มไปยังเหมือง , คอลเลกชันหนึ่งสมุทร
ฉัน -

5

ฉันต้องสร้างฟังก์ชั่นอาร์เรย์ที่ยืดหยุ่นเพื่อเพิ่ม "บันทึก" ลงไปตามที่ฉันต้องการและเพื่อให้สามารถอัปเดตและทำสิ่งที่จำเป็นในการคำนวณก่อนที่ฉันจะส่งไปยังฐานข้อมูลเพื่อการประมวลผลต่อไป นี่คือรหัสหวังว่าจะช่วย :)

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

อย่าลังเลที่จะเพิ่มประสิทธิภาพและ / หรือชี้ข้อบกพร่องใด ๆ :)


แล้วไงaLine.push([clmn1, clmn2, clmn3]);ล่ะ
Pimp Trizkit

5

นี่เป็นวิธีที่รวดเร็วที่ฉันพบว่าสร้างอาร์เรย์สองมิติ

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(null, null, null)

ตอนนี้เราได้สร้างอาร์เรย์ที่มีประชากรจริงแล้วสิ่งที่เราต้องทำคือเรียกmapและสร้างเลเยอร์ที่สอง ( y)


5

ด้านล่างหนึ่งสร้างเมทริกซ์ 5x5 และเติมด้วย null

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

console.log(md);


3
คำตอบนี้ผิด มันจะสร้างอาร์เรย์ที่มีอาร์เรย์เดียวกันเติมลงในช่องของมัน md[1][0] = 3 และองค์ประกอบที่เหลือทั้งหมดก็ได้รับการอัปเดตด้วย
Qiang

5

แถวและคอลัมน์ขนาดของอาร์เรย์ที่รู้จักกันเท่านั้นที่เวลาทำงานแล้ววิธีต่อไปนี้สามารถนำมาใช้สำหรับการสร้างอาร์เรย์ 2 มิติแบบไดนามิก

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

4

มีวิธีแก้ไขปัญหาอื่นที่ไม่ได้บังคับให้คุณกำหนดขนาดของอาร์เรย์ 2d ล่วงหน้าและมีความกระชับมาก

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

ใช้งานได้เนื่องจาก[1,2]แปลงเป็นสตริงที่ใช้เป็นคีย์สตริงสำหรับtableวัตถุ


คำตอบนี้เพียงอย่างเดียวทำให้ฉันไม่ต้องการยุ่งกับขยะที่เป็นอาร์เรย์ "หลายมิติ" ในจาวาสคริปต์แม้ว่าฉันจะมีวิธีการแก้ปัญหาที่สง่างามมากนอกจากนี้ยังแสดงให้เห็นว่าทุกคนไม่ได้สร้างอาร์เรย์หลายมิติเลยเพียงแค่ "อาร์เรย์" ใน JavaScript คำตอบนี้จะ "จำลอง" อาร์เรย์มิติขนาดไม่ จำกัด ขนาดไม่ จำกัด ของขนาดและเนื้อหาโดยพลการการเรียกซ้ำและห่วงคำตอบอื่น ๆ ทั้งหมดมีขีด จำกัด บนที่ต่ำกว่ามากกับขนาดของโครงสร้างอาร์เรย์ที่พวกเขาสามารถสร้างและการสร้าง ความเร็วจะเป็นปัญหาสำคัญสำหรับโครงสร้างที่มีขนาดใหญ่กว่านี้
Pimp Trizkit

ใช้บรรทัดนี้แทนการจำลองการเติมล่วงหน้า:var table = new Proxy({}, {get:(t,n)=>n in t ? t[n] : 42});
Pimp Trizkit

ดีวิธีที่สร้างสรรค์ในการ 'เลียนแบบ' Array2D โดยวัตถุ :)
Kamil Kiełczewski

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.