数组内边界的条件

时间:2017-08-10 13:58:11

标签: javascript arrays

我有一个矩阵,我有一个函数可以使用以下代码随机选取数组元素:

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?

感谢帮助。

2 个答案:

答案 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 = 1floor(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();
}