更新
我要做的是以块的形式迭代数组,将块的迭代方向交替到块。困惑?我也是。例如,如果我想通过一个包含25个元素的数组循环,但我想按此顺序执行:0,1,2,3,4,9,8,7,6,5,10 ,11,12,13,14,19,18,17,16,15,20,21,22,23,24,这样做最有效的方法是什么?我正在寻找可扩展的东西,因为我现在使用的数组实际上是225个元素,我想在15个元素块中遍历它,但这可能会在某些时候发生变化。到目前为止,我发现实际工作的唯一方法是将迭代顺序硬连接到第二个数组,然后以正常方式迭代,以获得原始数组的索引。但那很糟糕。任何帮助将不胜感激。
@Bergi要求提供一些示例代码。请不要打扰我太多。我还是个菜鸟:
function zeroPadNumber(theNumber, thePadding) {
var thePaddedNumber = thePadding.substring(0, (thePadding.length - theNumber.length)) + theNumber;
return thePaddedNumber;
}
var thisTile = 225;
var waveLoop = 15;
function mosaicWave() {
var theStartNum = thisTile;
for (w = 0; w < 15; w++) {
var theNum = theStartNum - w;
var theNumString = String(theNum);
var thePaddedNum = zeroPadNumber(theNumString, "000");
var theImgName = "sm_" + thePaddedNum;
var theNewSrc = theImgFolder + theImgName + "bg.gif";
document.images[theImgName].src = theNewSrc;
thisTile = theNum - 1;
if (waveLoop < 15) {
var prevStartTile = theStartNum + 15;
var thePrevNum = prevStartTile - w;
var thePrevNumString = String(thePrevNum);
var thePrevPaddedNum = zeroPadNumber(thePrevNumString, "000");
var thePrevName = "sm_" + thePrevPaddedNum;
var thePrevSrc = theImgFolder + thePrevName + ".gif";
document.images[thePrevName].src = thePrevSrc;
}
}
if (waveLoop == 1) {
var lastWave = function() {
var theStartNum = 15;
for (c = 0; c < 15; c++) {
var theNum = theStartNum - c;
var theNumString = String(theNum);
var thePaddedNum = zeroPadNumber(theNumString, "000");
var theImgName = "sm_" + thePaddedNum;
var theNewSrc = theImgFolder + theImgName + ".gif";
document.images[theImgName].src = theNewSrc;
}
}
setTimeout(lastWave, 100);
waveLoop = 15;
thisTile = 225;
} else {
waveLoop--;
setTimeout(mosaicWave, 100);
}
}
此代码段执行不同的动画。它从矩阵的右下角开始,并“打开”底行的15个图块。然后它向上移动一行,打开该行中的切片并关闭前一行中的切片。依此类推,直到顶行开启然后关闭。与我在新功能中尝试实现的自上而下的蛇形效果相比并不是很远。每排的倒车顺序是让我烦恼的主要原因。话虽如此,任何关于优化上述代码的建议也将受到高度赞赏。
更新1:
对我而言,这似乎应该有效,但事实并非如此。有谁能发现问题?
var loopRange = 225;
var blockRange = 15;
var theDirection = 1;
var weaveLoop = 0;
function mosaicWeave() {
var curObj, curSrc, lastObj, lastSrc;
var toggleLeadTile = function() {
alert(curSrc);
curObj.src = curSrc;
};
var toggleLastTile = function() {
lastObj.src = lastSrc;
};
while (weaveLoop < loopRange) {
imgNum = weaveLoop + 1;
imgName = "sm_" + zeroPadNumber(String(imgNum), "000");
if (imgNum < 15) {
//handle first row
curObj = document.images[imgName];
curSrc = theImgFolder + imgName + "bg.gif";
window.setTimeout(toggleLeadTile, 100);
} else if (imgNum == 225) {
//handle last row
curObj = document.images[imgName].src;
curSrc = theImgFolder + imgName + "bg.gif";
window.setTimeout(toggleLeadTile, 100);
for (i = 211; i < 226; i++) {
lastImgName = "sm_" + ((weaveLoop + 1) - 15);
lastObj = document.images[lastImgName];
lastSrc = theImgFolder + lastImgName + ".gif";
window.setTimeout(toggleLastTile, 100);
}
} else {
//handle middle rows
lastImgName = "sm_" + ((weaveLoop + 1) - 15);
curObj = document.images[imgName];
curSrc = theImgFolder + imgName + "bg.gif";
lastObj = document.images[lastImgName];
lastSrc = theImgFolder + lastImgName + ".gif";
window.setTimeout(toggleLeadTile, 100);
window.setTimeout(toggleLastTile, 100);
}
if (weaveLoop % blockRange == (theDirection == -1 ? 0 : blockRange - 1)) {
theDirection *= -1;
weaveLoop += blockRange;
} else {
weaveLoop += theDirection;
}
}
}
更新2:
感谢大家的投入。这有效:
var resetLoop = 1;
var weaveArray = new Array(225);
var weaveRange = 15, weaveDirection = 1, weaveIndex = 0, wInitLoop = 0;
function mosaicWeave() {
while (weaveIndex < 225) {
weaveArray[wInitLoop] = weaveIndex + 1;
if (weaveIndex % weaveRange == (weaveDirection == -1 ? 0 : weaveRange - 1)) {
weaveDirection *= -1;
weaveIndex += weaveRange;
} else {
weaveIndex += weaveDirection;
}
wInitLoop++;
}
mWeaveOn();
}
function mWeaveOff() {
var theNumString = String(weaveArray[resetLoop - 16]);
var theImgName = "sm_" + zeroPadNumber(theNumString, "000");
document.images[theImgName].src = "images/" + theImgName + ".gif";
mosaicArray[resetLoop - 1] = 0;
resetLoop++;
if (resetLoop < 226) {
setTimeout(mWeaveOn, 25);
} else if (resetLoop > 225 && resetLoop <= 240) {
setTimeout(mWeaveOff, 25);
} else {
resetLoop = 1;
}
}
function mWeaveOn() {
var theNumString = String(weaveArray[resetLoop - 1]);
var theImgName = "sm_" + zeroPadNumber(theNumString, "000");
document.images[theImgName].src = "images/" + theImgName + "bg.gif";
mosaicArray[resetLoop - 1] = 1;
if (resetLoop < 16) {
resetLoop++;
setTimeout(mWeaveOn, 25);
} else {
setTimeout(mWeaveOff, 25);
}
}
有没有人对是否有更有效的方法有意见?或者了解这可能会在不同平台/浏览器上或在不同情况下破坏?再次感谢。
答案 0 :(得分:4)
var arr = [0,1,2,3,4,5,6,7,8,9,10,11,11,13,14,15,16,17,18,19,20,21,22,23,24],
i = 0,
j = arr.length,
tmp,
chunk = 5;
while(i < j) {
tmp = arr.slice(i, i+=chunk);
if ((i / chunk) % 2 == 0) {
tmp = tmp.reverse();
}
console.log(tmp);
}
的 The demo. 强> 的
答案 1 :(得分:2)
这是一个灵活的解决方案,您可以根据需要更改块大小。
var index, max = 25;
for (var i = 0; i < max; i++) {
if (parseInt(i / 5) % 2)
index = parseInt(i / 5)*5 + 4 - i % 5;
else
index = i;
// use index as array index
foo(index);
}
如果你总是五的倍数,你可以硬编码五个元素的迭代,并做一个外部循环计数到max/5
并切换到正确的硬编码迭代。
var index, max = 25;
for ( var i=0; i<max/5; i++) {
if (i%2) {
foo(i*5+4);
foo(i*5+3);
foo(i*5+2);
foo(i*5+1);
foo(i*5+0);
} else {
foo(i*5+0);
foo(i*5+1);
foo(i*5+2);
foo(i*5+3);
foo(i*5+4);
}
}
答案 2 :(得分:1)
我想最简单,最清晰的解决方案是嵌套两个厕所:
var arr = new Array(25),
chunksize = 5;
for (var i=0; i<arr.length; i+=chunksize)
if (i % (chunksize*2))
for (var j=i+chunksize-1; j>=i; j--)
exec(j);
else
for (var j=i; j<i+chunksize; j++)
exec(j);
但是,你也可以只使用一个循环和循环计数器。在正确的位置(4,5,14,15,...)方向(增量/减量)将改变,计数器跳跃一个chunksize(4→9,5→10,14→19,......):
var arr = new Array(25),
chunksize = 5;
var dir = 1,
i = 0;
while (i<arr.length) {
exec(i); // or whatever you need to do
if (i % chunksize == (dir==-1 ? 0 : chunksize - 1)) {
dir *= -1;
i += chunksize;
} else
i += dir;
}
或者,在一个for-statement中:
for (var dir=1, i=0; i<arr.length; i+= (i+1)%chunksize == (dir==-1) ? (dir*=-1) && chunksize : dir)
exec(i); // or whatever you need to do
答案 3 :(得分:0)
此函数接受数组和块大小(在您的示例中为5)
function forwardAndBack(arr, blocksize){
var i, j, l = arr.length ;
for (i = 0 ; i < l ; i++){
if (i % (2 * blocksize) > (blocksize - 1)){
j = i + (blocksize - (2*(i % blocksize)))-1 ;
}
else {
j = i ;
}
arr[j] && myFunction(arr[j]) ; // In case you've gone too high
}
}
像这样使用:
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] ;
var result = [] ;
function myFunction(x){result.push(x)} ;
forwardAndBack(arr, 5);
console.log(result) ; // returns [0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14, 19, 18, 17, 16, 15, 20, 21, 22, 23, 24]