我有一个矩阵,我有一个函数可以使用以下代码随机选取数组元素:
npcSelectShip() {
let selectCol = () => {
let colIndex = Math.floor(Math.random() * this.npcSelectionField.length);
let selectCell = () => {
let cellIndex = Math.floor(Math.random() * this.npcSelectionField[colIndex].length);
if (this.npcSelectionField[colIndex][cellIndex].isEmpty === false) {
selectCell();
} else {
this.npcSelectionField[colIndex][cellIndex].isEmpty = false;
this.pickDirection(this.npcSelectionField, colIndex, cellIndex);
}
}
selectCell();
}
selectCol();
}
在此之后,我有另一个函数来搜索随机拾取元素的邻居(顶部,右侧,底部和左侧),随机选择一个邻居并更改属性:
pickDirection(field, col, cell) {
let neighbors = [];
neighbors.push(
field[col - 1][cell],
field[col + 1][cell],
field[col][cell - 1],
field[col][cell + 1]
);
let randDir = () => {
let randIndex = neighbors[Math.floor(Math.random() * neighbors.length)];
if (randIndex.isEmpty === false) {
randDir();
} else {
randIndex.isEmpty = false;
}
}
randDir();
}
我面临的问题是当随机拾取的元素的索引为0或等于数组长度时,因为如果它在index-1或index + 1选择邻居,它基本上是“越界”我收到这些错误:
TypeError: Cannot read property 'isEmpty' of undefined
TypeError: Cannot read property '9' of undefined
有没有办法解决这个问题,而不必编写一些ifs和elses?
感谢帮助。
答案 0 :(得分:0)
您可以使用logical OR ||
和默认模式,它返回一个空数组。
与concat
结合使用时,空数组充当中性值。
var neighbors = [].concat(
(field[col - 1] || [])[cell] || [],
(field[col + 1] || [])[cell] || [],
(field[col] || [])[cell - 1] || [],
(field[col] || [])[cell + 1] || []
);
或使用包装器进行访问
function getCell(array, col, cell) {
return (array[col] || [])[cell] || [];
}
使用
var neighbors = [].concat(
getCell(field, col - 1, cell),
getCell(field, col + 1, cell),
getCell(field, col, cell - 1),
getCell(field, col, cell + 1)
);
工作原理
(field[col - 1] || [])[cell] || []
它试图获得
的值field[col - 1]
如果值为
undefined
,field[col - 1] || []
它返回一个空数组,带有位置
Array.concat
运算符。我们得到的是field[col - 1]
数组或空数组[]
。对于下一个索引,我们使用相同的模式并检查是否
(field[col - 1] || [])[cell]
存在,如果没有,那么我们将另一个空数组作为结果
(field[col - 1] || [])[cell] || []
现在我们有一个truthy值,比如一个对象或一个空数组。
这是必要的,因为空数组不会添加到{{3}}的数组中。
答案 1 :(得分:0)
你基本上有两个选择:
第一个选项:不要在第一行/最后一行/列中拾取:
npcSelectShip() {
let selectCol = () => {
let colIndex = Math.floor(Math.random() * (this.npcSelectionField.length-2)) +1;
let selectCell = () => {
let cellIndex = Math.floor(Math.random() * (this.npcSelectionField[colIndex].length-2)) +1;
if (this.npcSelectionField[colIndex][cellIndex].isEmpty === false) {
selectCell();
} else {
this.npcSelectionField[colIndex][cellIndex].isEmpty = false;
this.pickDirection(this.npcSelectionField, colIndex, cellIndex);
}
}
selectCell();
}
selectCol();
}
(参见" -2"和" + 1" Math.random
函数调用后)
Math.floor(Math.random() * (length-2)) +1;
将在floor(0*(length-2)) +1 = 1
和floor(1*(length-2)) +1 = length-1
之间取一个数字
第二个选项:让条件不作为邻居添加超出范围的内容
pickDirection(field, col, cell) {
let neighbors = [];
if(col-1 >= 0) {
neighbors.push(field[col - 1][cell]);
}
if(col < field.length) {
neighbors.push(field[col + 1][cell]);
}
if(cell-1 >= 0) {
neighbors.push(field[col][cell -1]);
}
if(cell < field[col].length) {
neighbors.push(field[col][cell +1]);
}
let randDir = () => {
let randIndex = neighbors[Math.floor(Math.random() * neighbors.length)];
if (randIndex.isEmpty === false) {
randDir();
} else {
randIndex.isEmpty = false;
}
}
randDir();
}