简体   繁体   English

Javascript 多维数组更新特定元素

[英]Javascript multidimensional array updating specific element

I have a string that has been converted into an 2D Array in js.我有一个字符串已在 js 中转换为二维数组。

board = "...|.X.|...|" board = "...|.X.|...|"

It is used to represent a game board它用于表示游戏板

each.每个。 represents a space代表一个空间

each |每个 | represents a row代表一行

each X represents a wall每个X代表一堵墙

EDIT: code below for the 2d array creation编辑:下面的二维数组创建代码

var src= "...|.X.|...|";
board = src.split(/\|/g);

for (var i = 0; i < board.length; i++) {
var cells = board[i].split('');
for (var j = 0; j < cells.length; j++) {
    cells[j] = parseInt(cells[j]);
}
board[i][j] = cells;
console.log(board[1][1])
//returns 'X'

                    

when i access board[i][j] it returns correctly:当我访问 board[i][j] 它正确返回:

[0][0] = "." [0][0] =“。”

[1][1] = "X" [1][1] = “X”

[1][2] = "." [1][2] =“。”

etc etc等等等等

I want to update the specific element with a string representing a piece.我想用代表一块的字符串更新特定元素。 However when i insert into an element like so:但是,当我像这样插入一个元素时:

board[0][0] = "piece4" board[0][0] = "piece4"

The array returns in firebug as so:该数组在萤火虫中返回如下:

board = "piece4|.X.|...|" board = "piece4|.X.|...|"

When it should look like:当它应该看起来像:

board = ".piece4.|.X.|...|" board = ".piece4.|.X.|...|"

Why are elements [0][1] and [0][2] being overwritten?为什么元素 [0][1] 和 [0][2] 被覆盖? Am I not understanding arrays of array index access correctly in js?我是不是不理解 arrays 在 js 中正确访问数组索引?

I just had the same problem, but it had a more complex reason and I want to add it, in case someone finds this page searching for the same problem I had:我只是遇到了同样的问题,但它有一个更复杂的原因,我想添加它,以防有人发现此页面正在搜索我遇到的相同问题:

I had created and filled a 2-dimensional array like this:我创建并填充了一个二维数组,如下所示:

var foo = Array(n).fill(Array(n).fill(0));

which creates a 2-dimensional n*n array filled with zeroes.它创建了一个用零填充的二维 n*n 数组。

Now when I tried to overwrite a cell like this现在当我试图覆盖这样的单元格时

foo[1][1] = 1;

I ended up with these values:我最终得到了这些值:

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

which is really surprising IMHO.恕我直言,这真是令人惊讶。

The reason for this was, that there has only been one row, which had internally been referenced three times.这样做的原因是,有也不过才排,这已在内部被引用三次。 So when I changed the first index in "the second" row, it effectively changed all rows.因此,当我更改“第二”行中的第一个索引时,它有效地更改了所有行。

Bottom line: don't use Array.fill to create multi-dimensional arrays!底线:不要使用Array.fill创建多维数组!

PROBLEM:问题:

I'm betting that you have a one-dimensional array with strings stored in each.我敢打赌你有一个一维数组,每个数组都存储了字符串。 So your array actually looks like:所以你的数组实际上看起来像:

array (
    [0] => '...',
    [1] => '.X.',
    [2] => '...'
)

When this is what you want:当这是您想要的时:

array (
    [0] => array (
        [0] => '.',
        [1] => '.',
        [2] => '.'
    ),
    [1] => array (
        [0] => '.',
        [1] => 'X',
        [2] => '.'
    ),
    [2] => array (
        [0] => '.',
        [1] => '.',
        [2] => '.'
    )
)


SOLUTION:解决方案:

When constructing your 2D array, make sure you explicitly declare each entry in board as an array.构建二维数组时,请确保将board中的每个条目显式声明为数组。 So to construct it, your code might look something like this:因此,要构建它,您的代码可能如下所示:

board = new Array();
rows = 3;
for (var i = 0; i < rows; i++)
    board[i] = new Array('.', '.', '.');

I ran into a similar problem.我遇到了类似的问题。 So after reading a lot... this finally suited my needs.所以在阅读了很多之后......这终于符合我的需要。

myArr = [1,1,1];
var arr = new Array();

for (var i = 0; i < 10; i++) {
  arr[i] = Array.from(myArr);
}

//lets edit 3 positions
arr[0][1]= -1;
arr[3][2]= 100;
arr[8][0] = 8080;


for(var i=0; i<10; i++){
console.log(i + " === " + arr[i]);
}

OUTPUT: if you noticed only the edited index values changed... nothing else OUTPUT:如果您注意到只有编辑后的索引值发生了变化……没有别的

0 === 1,-1,1  <---
1 === 1,1,1
2 === 1,1,1
3 === 1,1,100 <---
4 === 1,1,1
5 === 1,1,1
6 === 1,1,1
7 === 1,1,1
8 === 8080,1,1 <---
9 === 1,1,1

The situation and solution given above is pretty simple.上面给出的情况和解决方案非常简单。 The issue of updating specific values in a list of objects (often referred to as an array, but that's a discussion for a different time) has more practical and industrial application.更新对象列表(通常称为数组,但这是不同时间的讨论)中的特定值的问题具有更多实际和工业应用。 The problem you tend to run into is thinking that looking at a value in a specific cell, eg my_array[0][0] returns 'some value' will also let you change that value through an assignment eg my_array[0][0] = 'new value'.您倾向于遇到的问题是认为查看特定单元格中的值,例如 my_array[0][0] 返回“某个值”也会让您通过赋值更改该值,例如 my_array[0][0] = '新值'。 You will find that depending on how you defined your array, the change shows in the same row across the columns, not what you are needing.您会发现,根据您定义数组的方式,更改显示在跨列的同一行中,而不是您需要的。 Look at the example code as an illustration of creating, and managing a multidimensional list of objects (array).将示例代码视为创建和管理多维对象列表(数组)的说明。

<html>
<head>
<title>JavaScript Object List/Array</title>
<script>
//Make a JavaScript array that can manage data of inventory between different locations over time.
var list_of_brands = ["BMW","Harley Davidson","Honda","Kawasaki"];
var list_of_locations = ["Dayton","Cincinnati"];

//a month of data
var DAYS_IN_A_MONTH = 30;
var calendar = [];
for(day_of_sales = 1; day_of_sales <= DAYS_IN_A_MONTH; day_of_sales++){

  //hold your locations
  var shop_location = [];//You need to create a new array for each day - that's part of the trick!

  for(location_index = 0;location_index < list_of_locations.length;location_index++){

  //set up some starting inventory
  var inventory = [];//You need to create a new array for each location - that's part of the trick!

      for(brand_index = 0; brand_index < list_of_brands.length; brand_index++){ 

        inventory[list_of_brands[brand_index]] = {"brand": list_of_brands[brand_index], "on_hand": 10,"sold": 0};

      };//end inventory loop

      shop_location[list_of_locations[location_index]] = {"city":list_of_locations[location_index],inventory};

  }//end location loop

  calendar[day_of_sales] = {"Day": day_of_sales, shop_location};

}//end calendar loop

//check your work
console.log('calendar:'); console.log(calendar);
console.log('shop_location:'); console.log(shop_location);
console.log('specific information: '); console.log(calendar[1].shop_location["Dayton"].inventory['BMW'].brand);//returns 'BMW'
console.log('change Dayton.BMW information: '); console.log(calendar[1].shop_location["Dayton"].inventory['BMW'].brand="Triumph");//change value
console.log('check work (Dayton.BMW): '); console.log(calendar[1].shop_location["Dayton"].inventory['BMW'].brand);//check work - PASS
console.log('check work (Cincinnati.BMW): '); console.log(calendar[1].shop_location["Cincinnati"].inventory["BMW"].brand);//check work other location - PASS!!

//Make some lasting and specific changes
console.log("Now make a change in the month's value over showing a sale on the 13th");
var sale_date = 13;
console.log("date of sale " + sale_date + "th");

var original_number_on_hand = calendar[sale_date].shop_location["Dayton"].inventory["BMW"].on_hand;
console.log("original_number_on_hand on that date: " + original_number_on_hand);

var number_of_units_sold = 3;
console.log("number_of_units_sold on that date: " + number_of_units_sold);

var new_inventory_level = original_number_on_hand - number_of_units_sold;
console.log("new_inventory_level: " + new_inventory_level);

for(date_index = sale_date; date_index  <= DAYS_IN_A_MONTH; date_index ++){  
  calendar[date_index].shop_location["Dayton"].inventory["BMW"].sold = number_of_units_sold;
  calendar[date_index].shop_location["Dayton"].inventory["BMW"].on_hand = new_inventory_level;
}

console.log("Show change in inventory");
  console.log(list_of_locations[0]+" has " + calendar[10].shop_location["Dayton"].inventory["BMW"].on_hand + " " + list_of_locations[1]+" has " + calendar[10].shop_location["Cincinnati"].inventory["BMW"].on_hand);
  console.log(list_of_locations[0]+" has " + calendar[11].shop_location["Dayton"].inventory["BMW"].on_hand + " " + list_of_locations[1]+" has " + calendar[11].shop_location["Cincinnati"].inventory["BMW"].on_hand);
  console.log(list_of_locations[0]+" has " + calendar[12].shop_location["Dayton"].inventory["BMW"].on_hand + " " + list_of_locations[1]+" has " + calendar[12].shop_location["Cincinnati"].inventory["BMW"].on_hand);
  console.log(list_of_locations[0]+" has " + calendar[13].shop_location["Dayton"].inventory["BMW"].on_hand + " " + list_of_locations[1]+" has " + calendar[13].shop_location["Cincinnati"].inventory["BMW"].on_hand);
  console.log(list_of_locations[0]+" has " + calendar[14].shop_location["Dayton"].inventory["BMW"].on_hand + " " + list_of_locations[1]+" has " + calendar[14].shop_location["Cincinnati"].inventory["BMW"].on_hand);
  console.log(list_of_locations[0]+" has " + calendar[15].shop_location["Dayton"].inventory["BMW"].on_hand + " " + list_of_locations[1]+" has " + calendar[15].shop_location["Cincinnati"].inventory["BMW"].on_hand);
  console.log(list_of_locations[0]+" has " + calendar[16].shop_location["Dayton"].inventory["BMW"].on_hand + " " + list_of_locations[1]+" has " + calendar[16].shop_location["Cincinnati"].inventory["BMW"].on_hand);

  //add new items to a shop's inventory
var inventory_2 =[];
for(brand_index = 0; brand_index < list_of_brands.length; brand_index++){ 

  inventory_2[list_of_brands[brand_index]] = {"brand": list_of_brands[brand_index], "on_hand": 10,"sold": 0};

};//end inventory loop
console.log("show inventory_2");console.log(inventory_2);
console.log("add inventory");inventory_2["Indian"] = {"brand": "Indian", "on_hand": 10,"sold": 0};
console.log("show updated inventory_2");console.log(inventory_2);

</script>
</head>
<body>
  <p>look in the JavaScript console for output</p>
</body>
</html>

An other way to create a 2D array in javascript is to use Array.from function在 javascript 中创建二维数组的另一种方法是使用Array.from函数

  var 2Darr =  Array.from(Array(5), () => {
                 return new Array(5).fill(0)
             })

This will create a 5 x 5 array completely filled with 0. Array.from takes two parameters, the first one is an javascript iterable Object to extract the array from, the second one is an optional callback where we can specify something to apply to the array elements.这将创建一个完全填充为 0 的 5 x 5 数组。 Array.from有两个参数,第一个是用于提取数组的 javascript 可迭代对象,第二个是可选的回调,我们可以在其中指定要应用于数组元素。

Accessing the element can be done simply like in other languages.可以像在其他语言中一样简单地访问元素。

Two remarks here:这里有两点说明:

  1. Arrays start with index 0 in every dimension.数组从每个维度的索引 0 开始。
  2. If you access a string as a 2D array, every element is a char rather than a string.如果将字符串作为二维数组访问,则每个元素都是字符而不是字符串。

So if you write board[0][0] = 'X';所以如果你写board[0][0] = 'X'; then you get the right behavior (and that changes the first character of the string, not the second).然后你会得到正确的行为(这改变了字符串的第一个字符,而不是第二个)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM