JS为什么将整数变量重置为初始值,而不是将数组变量重置为初始值?

时间:2018-07-07 01:55:15

标签: javascript arrays ecmascript-6 scope graph-algorithm

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

下面的算法有效,但是仅当我将所有岛保存在数组中时,才使用“ 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] ])

2 个答案:

答案 0 :(得分:1)

函数biggest中的变量bigIsland独立于biggest中的变量checkIsland。在一个函数中更改变量对另一函数没有影响。数组是不同的,因为当您传递数组时,会在变量中获得对同一数组的引用。考虑:

function one() {
  let variable = 0;
  console.log("variable in on before calling two ", variable)

  two(variable)
  console.log("variable in on after calling two ", variable)
}

function two(variable) {
  variable += 200
  console.log("variable in two", variable)
}

one()

如果您希望两个函数都更改同一个变量,则可以将变量放在一个范围内,都可以看到:

let variable = 0
function one(){
    console.log("variable in on before calling two ", variable)

    two()
    console.log("variable in on after calling two ", variable)
}

function two() {
    variable += 200
    console.log("variable in two", variable)
}

one()

或者您可以将其作为对象传递,这是传递事物的相当标准的方法:

function one() {
  let obj = {variable: 0}
  console.log("variable in on before calling two ", obj.variable)

  two(obj)
  console.log("variable in on after calling two ", obj.variable)
}

function two(obj) {
  // notice we are not reassigning the variable obj with obj = 200
  //  but changing the thing obj refers to
  obj.variable += 200
  console.log("variable in two", obj.variable)
}

one()

答案 1 :(得分:1)

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

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是一个 array ,它是一个对象(非基元),因此当islandscheckIsland内部被突变,其更改在其他任何地方也可见。引用非基本体的变量实质上是对对象在内存中的存储位置的引用-传递时对象不会被复制,除非您明确地这样做。