【问题标题】:JS scope for merge sorting please help me understnadJS合并排序范围请帮我理解
【发布时间】:2021-07-22 03:27:52
【问题描述】:

有人可以帮我理解为什么第一段代码有效,而第二段无效吗?试图解决按顺序合并到数组的问题。第一个是解决方案代码,第二个是我想出的代码。 我无法解决为什么 i 变量似乎停留在工作循环中的循环中,但在我的代码中,当尝试在 while 循环中使用它时,arr1Item 似乎消失了?

const gerry = [0,3,4,31] 
const machmoud = [4,6,30]

const mergeSort = (arr1, arr2) => {
  const mergedArr = [];
  //init Counters
  let i= 1
  let j= 1
  let arr1Item = arr1[0]
  let arr2Item = arr2[0]
  
  while(arr1Item || arr2Item){        
    if(arr1Item < arr2Item || !arr2Item){
      mergedArr.push(arr1Item)
      arr1Item = arr1[i]
      i++
    }
      else{
        mergedArr.push(arr2Item)
        arr2Item = arr2[j]
        j++
      }
    
  }
  return mergedArr
}

console.log(mergeSort(gerry, machmoud))

第二组代码

const gerry = [0,3,4,31] 
const machmoud = [4,6,30]

const mergeSort = (arr1, arr2) => {
  const mergedArr = [];
  //init Counters
  let i= 0
  let j= 0
  let arr1Item = arr1[j]
  let arr2Item = arr2[i]
  
  while(arr1Item || arr2Item){        
    if(arr1Item < arr2Item || !arr2Item){
      mergedArr.push(arr1Item)
      i++
    }
      else{
        mergedArr.push(arr2Item)
        j++
      }
    
  }
  return mergedArr
}


console.log(mergeSort(gerry, machmoud))

这会陷入无限循环。

【问题讨论】:

  • 当输入数组中的值为零时,这两种实现都可能出错。当两个输入数组都以零开头时,肯定会出错。

标签: javascript arrays scope mergesort


【解决方案1】:

您的代码(第二个块)的主要问题是循环永远不会更新arr1Itemarr2Item 的值,因此while 条件永远不会计算出除第一个之外的任何其他值时间。因此你得到一个无限循环。所以一旦你改变ij应该也应该从数组中读取相应的值到相关的变量中。

但是,这两种实现都存在一个问题。如果他们得到两个数组,它们的第一个数组值都为 0,或者即使只有第二个数组以 0 开头,结果也不会像预期的那样。您真的应该与undefined 进行比较。这是您更正的代码:

const gerry = [0, 3, 4, 31];
const machmoud = [4, 6, 30];

const mergeSort = (arr1, arr2) => {
  const mergedArr = [];
  //init Counters
  let i = 0;
  let j = 0;
  let arr1Item = arr1[i];
  let arr2Item = arr2[j];

  while (arr1Item !== undefined || arr2Item !== undefined) {
    if (arr1Item < arr2Item || arr2Item === undefined) {
      mergedArr.push(arr1Item);
      i++;
      arr1Item = arr1[i];
    } else {
      mergedArr.push(arr2Item);
      j++;
      arr2Item = arr2[j];
    }
  }
  return mergedArr;
}

console.log(mergeSort(gerry, machmoud));

【讨论】:

  • 好的,所以即使 i 正在更新,它也不会更新要为 for while 循环评估的 arr1item 和 arr2item 变量。这是范围问题吗,因为在我看来,由于 i 更新,它从外部更新变量,该变量正在被评估以运行 while 循环,这对我来说仍然是正常的。即使我理解它不起作用的原因,我也很难直观地理解它。
  • 确实如此。 i 本身就是一个变量。它与数组无关。这并不是因为您曾经使用i 作为数组的索引,所以i 会以某种方式“链接”到该数组。您可以将 i 用于很多事情,但无论您如何使用它都不会与任何其他对象或数组“结婚”。因此,每次更新i 的值时,您都需要“同步”您认为应该维护的任何依赖项。
  • 好的,谢谢你的解释。我想我需要再看几次才能让它成为一种本能。最后一个想法:当我创建一个while循环时,我应该自动假设启动while循环的变量(如果它是一个变量)需要在while循环内重新分配,以便能够改变条件并退出循环?
  • 如果你的while条件是while (arr1[i] !== undefined || arr2[i] !== undefined),那么你甚至不需要那些arr1Item变量,然后你只需增加ij就足够了。这行得通,因为 while 条件将采用 i 的新值并在 arr1, ... 每个 迭代中执行相应值的查找。
  • 你能做的最好的事情是(1)使用调试器(控制台)在步骤期间监视变量(iarr1Item、...等)的值通过逐步执行您的代码。真正学会使用这个开发工具。它属于开发人员的基本工具包。然后 (2) 绘制每个变量作为值或作为参考的内存映射。如果你做对了,所有的疑虑都会消失。
猜你喜欢
  • 2015-01-23
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 2022-11-26
相关资源
最近更新 更多