【问题标题】:JavaScript for loop confusionJavaScript for 循环混淆
【发布时间】:2016-06-16 02:32:56
【问题描述】:

我正在编写我认为简单的 for 循环,但它的行为方式并不符合我的预期。我想了解它为什么会这样做:

function pair(str) {

  var finalArray = [];
  var pushArray  = [];
  
  var lookup = {
    G: "C",
    C: "G",
    A: "T",
    T: "A"
  };
  
  for (i=0; i<str.length; i++) {
    pushArray[0] = str[i];
    pushArray[1] = lookup[str[i]];
    finalArray.push(pushArray);
  }
  return finalArray;
}

pair("ATCGG");

我希望它返回 [["A","T"],["T","A"],["C","G"],["G","C"],[ "G","C"]]

我实际上得到的是 [["G","C"],["G","C"],["G","C"],["G","C"] ,["G","C"]]

似乎所有的 ["G","C"] 都是针对 i = 4 的。为什么我的代码没有循环?我错过了什么?

【问题讨论】:

  • 只有一个pushArray,并且您在循环的每次迭代中重复使用它。您必须在每次迭代时创建一个 new 数组,以使其按您期望的方式工作。
  • 我以为每次 for 循环运行时我都在重新定义 pushArray[0] 和 pushArray[1]? JS 不允许你在 for 循环中这样做吗?
  • 添加pushArray = []; 作为循环内部的第一条语句。这将形成一个全新的阵列。您只是一遍又一遍地在列表中推送相同的数组。
  • 啊啊啊啊啊……非常感谢!!
  • 警告:您在for 循环中使用未声明的变量i 是一个等待发生的重大错误。在严格模式下运行您的代码,这将是一个错误(因此您不会意外地以这种方式编写代码)。始终声明任何局部变量。

标签: javascript arrays object for-loop


【解决方案1】:

试试这个 - 注意原来的帖子是确定 DNA 代码中的碱基对序列。我提供以下内容。碱基数组(在 OP 中查找)的关键是知道每个遗传碱基只能与预定的其他碱基配对以提供以下组合(G-C、C-G、A-T、T-A)。因此碱基数组可以简化,然后遍历传递的字符串,在碱基数组中找到该特定碱基的第一个索引并将其与下一个索引匹配(以形成碱基对)就很简单了。然后只需将这对推入 DNA 序列阵列。请注意,我是“console.logging”它 - 以证明它有效 - 而不是使用“return”。

遗传学知识即使在编程中也很有用:)

pair("ATCGG");

function pair(str) {
  var DNAsequence = [];
  var bases = ["G","C","G","A","T","A"];

  for (i=0; i<str.length; i++) {
      var firstBase=bases.indexOf(str[i]);
      var secondBase=firstBase+1;
      var basePair=[bases[firstBase],bases[secondBase]];

    DNAsequence.push(basePair);
  }
  console.log( DNAsequence);
}

console.log 会按要求显示以下内容:

[["A","T"], ["T","A"], ["C","G"], ["G","C"], ["G","C"]]

【讨论】:

    【解决方案2】:

    问题是finalArray.push(pushArray) 没有复制pushArray。每次执行此操作时,都会推送对同一数组的引用,然后在下一次迭代中对其进行修改。每次都需要创建一个新数组。

    function pair(str) {
    
      var finalArray = [];
      var pushArray;
      
      var lookup = {
        G: "C",
        C: "G",
        A: "T",
        T: "A"
      };
      
      for (var i=0; i<str.length; i++) {
        pushArray = [];
        pushArray[0] = str[i];
        pushArray[1] = lookup[str[i]];
        finalArray.push(pushArray);
      }
      return finalArray;
    }

    【讨论】:

    • 解释 OP 中问题的唯一答案。
    • 所以您在该函数中对pushArray 所做的任何更改都会修改finalArray 包含的所有值?
    • 正确,因为它们都是同一个数组。
    【解决方案3】:

    您的假设部分正确,除了每次您推送对同一变量的引用。

    这应该可行:

    function pair(str) {
    
      var finalArray = [];
    
    
      var lookup = {
        G: "C",
        C: "G",
        A: "T",
        T: "A"
      };
    
      for (i=0; i<str.length; i++) {
      var pushArray=[];
        pushArray[0] = str[i];
        pushArray[1] = lookup[str[i]];
        finalArray.push(pushArray);
      }
      console.log(finalArray.toString())
      return finalArray;
    }
    
    pair("ATCGG");
    

    Fiddle

    【讨论】:

    • 不是范围问题,只是 OP 的代码不断将引用推送到同一个数组。 OP 的代码中没有全局变量。将 var 移动到 for 循环中没有区别,因为使用 var 创建的变量具有函数作用域,而不是块作用域。唯一重要的是移动 = [] 部分,以便在每次迭代中创建一个新数组。
    • @nnnnnn 是的,你是对的,删除了范围部分。
    【解决方案4】:

    只需替换这个:

    finalArray.push(pushArray);
    

    有了这个:

    finalArray = finalArray.concat(pushArray);
    

    【讨论】:

      【解决方案5】:

      在您的代码中,pushArray 是单个实例对象,并且每次在 for 循环中都会被新值覆盖。 您可以为每个 str-lookup 对创建单独的对象实例来修改您的代码,如下所示。

      function pair(str) {
      
        var finalArray = [];
        
        var lookup = {
          G: "C",
          C: "G",
          A: "T",
          T: "A"
        };
        
        for (i=0; i<str.length; i++) {
          finalArray.push([ str[i], lookup[str[i]] ]);
        }
        return finalArray;
      }
      
      var res = pair("ATCGG");
      alert(JSON.stringify(res));

      希望对你有所帮助。

      【讨论】:

        【解决方案6】:

        这应该对你有帮助:)

        function pair(str) {      
          var lookup = {
            G: 'C',
            C: 'G',
            A: 'T',
            T: 'A'
          };
          return str.split('').reduce(function(ys,x) {
            return ys.concat([[x, lookup[x]]]);
          }, []);
        }
        
        var result = pair('ATCGG');
        console.log(JSON.stringify(result));
        // [["A","T"],["T","A"],["C","G"],["G","C"],["G","C"]]

        【讨论】:

        • 谢谢!我还有很多东西需要学习....认为这将是一个简单的问题:/
        猜你喜欢
        • 2018-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-27
        • 2016-05-05
        • 2015-09-12
        • 1970-01-01
        相关资源
        最近更新 更多