我用这个算法把头发拉了出来。目标是将数字数组作为输入并输出一个字符串,其中所有序列号都显示为范围。例如,如果我的输入是[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));
答案 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)
根据您的要求更新代码:
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;
你的内部for循环逻辑是不正确的。我已更新代码以满足要求。
答案 2 :(得分:0)
范围是代码中可直接访问变量的区域。
在JS范围内由function
定义{
,}
和let
的块(即const
和catch
)块。
以下似乎有效:
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);