【问题标题】:Javascript variable assignment in nested for loop嵌套for循环中的Javascript变量赋值
【发布时间】:2016-09-13 16:56:49
【问题描述】:

我正在用这个算法拉扯我的头发。目标是将数字数组作为输入并输出一个字符串,该字符串将所有连续数字显示为一个范围。例如,如果我的输入是 [1,2,4,6,7,8,] 我的输出应该是“1-2,4,6-8”。我的问题在于嵌套 for 循环的 if 语句中的变量赋值。每次 j 增加时,IndexEn 都会被覆盖,并且最终应该作为最高值退出内部循环。问题是,当我尝试在 for 循环之外调用变量时,它会传递 IndexEn 的每个值而不是最大值。我不明白 IndexEn 在内部循环仍在运行时如何能够超出内部循环的范围?有人可以帮我解决并了解这里发生的事情吗?

function bkInd(arr){
    var bookSt="";
    var indexSt;
    var indexEn;
    for(var i =0;i<arr.length-1;i++){       
        if(arr[i+1] !== (arr[i]+1)) {
            if(i===0 || (i>0 && arr[i]) !== (arr[i-1]+1) ){
                bookSt+= arr[i]+",";
            }
        // check to see if number are sequential and SHOULD output starting index value - last value    
        }else{
            for(var j=i+1;j<arr.length;j++){
                    var count=0;    
                if(arr[j]==(arr[i +count]+1)){
                     indexSt = arr[i];
                     indexEn = arr[j];
                    count+=1;   
                }
            }
            //concatenate string 
            //console.log(indexEn); for value of index 
            bookSt+= indexSt+"-"+indexEn+",";
        }       
    }
    return bookSt;
}
var bookList = [1,3,4,5,7,9,10,11];
document.write(bkInd(bookList));

【问题讨论】:

    标签: javascript for-loop scope


    【解决方案1】:

    我不喜欢嵌套循环(在大型数据集上可能会很慢),所以我采用了不同的方法,希望您不要介意:

    var bkInd = function(arr) {
        var result = [];
        var seq = []; // 'Temporary' array
    
        for(var i = 0; i < arr.length; i++) {
            seq.push(arr[i])
            if(arr[i] + 1 !== arr[i + 1]) {
                result.push(seq.length > 1 ? seq[0] + '-' + seq.pop() : arr[i]);
                seq = [];
            }
        }
        return result.join(', ')
    }
      // => '1, 3-5, 7, 9-11'
    

    当它循环通过 arr 时,它会“构建”一个临时数字数组 (seq)。如果下一个数字是连续的,seq 会保留最后一个数字并继续循环。如果下一个数字比当前数字高一个以上,则seq 被推送到result,但如果seq 的索引长度超过一个,它将把这些连接成一个连字符的字符串。在seq 被推送后,它被重置为一个空数组。最后,它用逗号加入result 数组。

    【讨论】:

      【解决方案2】:

      代码根据您的要求更新:

      function bkInd(arr){
          var bookSt="";
          var indexSt;
          var indexEn;
          for(var i =0;i<arr.length-1;i++){       
              if(arr[i+1] !== (arr[i]+1)) {
                  if(i===0 || (i>0 && arr[i]) !== (arr[i-1]+1) ){
                      bookSt+= arr[i]+",";
                  }
              // check to see if number are sequential and SHOULD output starting index value - last value    
              }else{
              	var count=1;
              	indexSt = arr[i];
                  for(var j=i;j<arr.length;j++){
                      
                      if(arr[j]==(indexSt+count)){
                          indexEn = arr[j];
                          count+=1;
                          i++;
                      }
                  }
                  //concatenate string 
                  //console.log(indexEn); for value of index 
                  bookSt+= indexSt+"-"+indexEn+",";
              }       
          }
          return bookSt;
      }
      var bookList = [1,3,4,5,7,9,10,11];
      console.log(bkInd(bookList));

      您的内部 for 循环逻辑不正确。我已经更新了代码以满足要求。

      【讨论】:

        【解决方案3】:

        作用域是可以直接访问变量的代码区域。

        在 JS 范围内由functions 定义,块(即{})用于letconstcatch 块。

        以下似乎有效:

        function runnify(arr) {
            var runFrom;
            return arr.reduce((p,c,i)=>{
                if (c + 1 === arr[++i]) { // true if next item is sequential            
                    if (runFrom == null ) { // We are at start of run                
                        runFrom = c;
                    }
                    return p;
                }
                
                if (runFrom) { // We are at the end of a run            
                    p.push(`${runFrom}-${c}`);
                    runFrom = null;
                    return p;
                }
                
                p.push(c); // Not sequential
                return p;        
            }, []).join(',');
        }
        var seq = [1, 3, 4, 5, 7, 9, 10, 11];
        document.write(runnify(seq));

        【讨论】:

          【解决方案4】:

          基本上,您可以使用检查收集所有项目,如果在数组中连续并在末尾加入,连续元素使用破折号,其余元素使用逗号。

          function consecutive(array) {
              return array.reduce(function (r, a,i) {
                  var last = r[r.length - 1];
                  if (!i || last[last.length - 1] + 1 !== a) {
                      r.push([a]);
                  } else {
                      last[1] = a;
                  }
                  return r;
              }, []).map(function (a) { return a.join('-'); }).join();
          }
          
          var array = [1, 3, 4, 5, 7, 9, 10, 11],
              grouped = consecutive(array);
          
          console.log(grouped);

          【讨论】:

            猜你喜欢
            • 2014-02-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-12-27
            • 2014-01-21
            • 2018-12-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多