嵌套for循环

时间:2016-09-13 16:56:50

标签: javascript for-loop scope

我用这个算法把头发拉了出来。目标是将数字数组作为输入并输出一个字符串,其中所有序列号都显示为范围。例如,如果我的输入是[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));

4 个答案:

答案 0 :(得分: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'

反而建立起来&#39;循环遍历seq的临时数字数组(arr)。如果下一个数字是顺序的,seq保留最后一个数字并继续循环。如果下一个数字比当前数字高一个以上,则seq被推送到result,但如果seq多于一个索引,则会将这些数字连接到带连字符的字符串。推送seq后,它将重置为空数组。最后,它用逗号连接result数组。

答案 1 :(得分:0)

根据您的要求更新代码:

&#13;
&#13;
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));
&#13;
&#13;
&#13;

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

答案 2 :(得分:0)

范围是代码中可直接访问变量的区域。

在JS范围内由function定义{}let的块(即constcatch)块。

以下似乎有效:

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));

答案 3 :(得分:0)

基本上,您可以使用支票收集所有项目,如果是连续的数组并在最后加入,连续的元素用短划线,其余的用逗号。

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);