javascript - JS 为什么整型变量被重置为初始值,而数组变量却没有?

标签 javascript arrays ecmascript-6 scope graph-algorithm

给定一个矩阵/图形/多维数组的输入(不太确定这些在编程中是否有唯一的定义),下面的函数应该输出最大岛屿的大小。陆地用 1 表示,水用 0 表示,两个有陆地的区域只有在水平或垂直(不是对 Angular 线)相邻时才连接。

下面的算法有效,但只有当我将所有岛屿保存在数组中时才是“islands”变量,然后返回保存的最大值。

最初,我试图仅跟踪“最大”变量的最大值的大小。然而,由于某种原因,它不断被重置为初始值 0。

为什么会发生这种情况?我特别困惑为什么这种情况会发生在“最大”变量而不是“岛屿”变量上,因为两者似乎具有完全相同的范围。

const bigIsland = matrix => {
  let biggest = 0
  let islands = []
  let visited = matrix.map(row => row.map(node => false))
  for(let y=0; y<matrix.length; y++){
    for(let x=0; x<matrix[y].length; x++){
      if (visited[y][x]) continue
      checkIsland(matrix, visited, y, x, islands, biggest)
    }
  }
  return Math.max(...islands)
}

const checkIsland = (matrix, visited, y, x, islands, biggest) => {
  console.log("biggestStart", biggest)
  console.log("islandsStart", islands)
  let currIsland = 0
  let nodesToCheck = [[y,x]]
  while(nodesToCheck.length){
    const [y, x] = nodesToCheck.pop()
    if (visited[y][x]) continue
    visited[y][x] = true
    if (matrix[y][x]===0) continue
    currIsland++
    console.log("currIsland", currIsland)
    getValidNeighbors(matrix, visited, y, x, nodesToCheck)

  }
  if (currIsland > biggest) biggest = currIsland
  if (currIsland > 0) islands.push(currIsland)
  console.log("biggest", biggest)
  console.log("islands", islands)
}

const getValidNeighbors = (matrix, visited, y, x, nodesToCheck) => {
  if(y>0) nodesToCheck.push([y-1, x])
  if(y<matrix.length-1) nodesToCheck.push([y+1, x])
  if(x>0) nodesToCheck.push([y, x-1])
  if(x<matrix[y].length-1) nodesToCheck.push([y, x+1])
}

bigIsland([ [1, 0, 1], 
            [1, 0, 1], 
            [1, 0, 0] ])

最佳答案

当您将原始变量传递给函数时(例如将 biggest 传递给 checkIsland),该函数中的任何内容都无法更改原始引用到调用函数中的该变量。为了更改 bigIsland 中的 biggest,您需要从 checkIsland 显式返回找到的 biggest:

const bigIsland = matrix => {
  let biggest = 0
  let islands = []
  let visited = matrix.map(row => row.map(node => false))
  for(let y=0; y<matrix.length; y++){
    for(let x=0; x<matrix[y].length; x++){
      if (visited[y][x]) continue
      biggest = checkIsland(matrix, visited, y, x, islands, biggest)
    }
  }
  return Math.max(...islands)
}

const checkIsland = (matrix, visited, y, x, islands, biggest) => {
  console.log("biggestStart", biggest)
  console.log("islandsStart", islands)
  let currIsland = 0
  let nodesToCheck = [[y,x]]
  while(nodesToCheck.length){
    const [y, x] = nodesToCheck.pop()
    if (visited[y][x]) continue
    visited[y][x] = true
    if (matrix[y][x]===0) continue
    currIsland++
    console.log("currIsland", currIsland)
    getValidNeighbors(matrix, visited, y, x, nodesToCheck)

  }
  if (currIsland > biggest) biggest = currIsland
  if (currIsland > 0) islands.push(currIsland)
  console.log("biggest", biggest)
  console.log("islands", islands)
  return biggest;
}

const getValidNeighbors = (matrix, visited, y, x, nodesToCheck) => {
  if(y>0) nodesToCheck.push([y-1, x])
  if(y<matrix.length-1) nodesToCheck.push([y+1, x])
  if(x>0) nodesToCheck.push([y, x-1])
  if(x<matrix[y].length-1) nodesToCheck.push([y, x+1])
}

bigIsland([ [1, 0, 1], 
            [1, 0, 1], 
            [1, 0, 0] ])

另一方面,当你传递islands时,islands是一个数组,它是一个对象(非原始),所以当islandscheckIsland内部发生突变时,它的变化也将在其他地方可见。引用非基元的变量本质上是对内存中对象的内存位置的引用 - 对象在传递时不会被复制,除非您明确这样做。

关于javascript - JS 为什么整型变量被重置为初始值,而数组变量却没有?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51219309/

相关文章:

arrays - TypeScript - 数组 toString()

javascript - ES6类中类/模块类

javascript - Babel 下调用 super() 自定义错误无法输出堆栈?

javascript - Electron 选择带有文本输入和 onclick 事件的目录

javascript - svg- Sprite : symbol conversion to single svg icon

javascript - 我的错误在哪里 - Javascript/jQuery 中选择框的日期计算器?

javascript - 映射 JS 对象并将参数合并到子对象中

javascript - 如何验证输入日期 html 年份?

javascript - Jquery inArray() 方法在 Jquery 对象中查找类

javascript - Array.push() 和 Spread 语法之间的区别