Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Setting different vars in for loop?

Guest
Jan 26, 2013 Jan 26, 2013

Hi

I have a reasonable large loop, and I want it to loop one of two ways depending on conditions before it...

1. for (var i:int = searchHit; i< array.length; i++)

or

2. for (var i:int=array.length; i>=0; i--)

I'm wondering if there is a way to set up vars to populate the above to avoid writing out two identical oops with different conditions?

I can do this...

var _inc = "++" (or "--") depending on previous code

var _range = array.length;

for (var i:int = _range; i< array.length; i[inc])

...but I'm unsure how to put i< array.length or i>=0 into a var to insert (or if it's even possible)?

Thanks for your help.

TOPICS
ActionScript
1.3K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jan 26, 2013 Jan 26, 2013

you could use one 'do' or 'while' loop but it's faster to do what you're currently doing.  though, it would look a little more elegant and be easier to debug and maintain if you called a function inside your loops:

if( NEXT){

for (var i:int = searchHit; i< array.length; i++) {

evalF(i);

} else {

for (i=searchHit; i>=0; i--){

evalF(i);

}

Translate
Community Expert ,
Jan 26, 2013 Jan 26, 2013

unless you can decrease the iterations by many billions, it will be probably more efficient to loop backwards and NOT test for the shortest path through your loop.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 26, 2013 Jan 26, 2013

In that situation you'd set a custom flag but still need multiple loops the rest of the code you didn't share actually needs both of those loops.

e.g.

var dataComplete:Boolean = false;

// run both loops as mentioned above just how they are (except change i if it's a nested loop)

// once complete in the final loop

dataComplete = true;

if (dataComplete) { break; }

It depends on what your data is and what you're really trying to do. Explaining it more will issue a better strategy.

edit:

Kglad! On the same minute.. haha

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 26, 2013 Jan 26, 2013

Hang on - I buggered it up, and should explain more what I'm trying to do...

1. for (var i:int = searchHit; i< array.length; i++)

or

2. for (var i:int=searchHit; i>=0; i--)

I have a NEXT and PREVIOUS button that searches for and selects the next or previous row that matches a keyword the user enters.

So if the get 100 rows in hitting NEXT, then hit PREVIOUS, I want it to start searching from the row it's at, not the end or the beginning

(in a prior bit of code, I searchHit++ or -- (depending on NEXT or PREVIOUS) to make sure it starts looking after or before the last hit)

The above loop set ups seem to work if I use them like:

If NEXT do this loop - for (var i:int = searchHit; i< array.length; i++) else do this loop for (var i:int=searchHit; i>=0; i--)

...with identical loops for each one.

Cheers guys

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 26, 2013 Jan 26, 2013

you could use one 'do' or 'while' loop but it's faster to do what you're currently doing.  though, it would look a little more elegant and be easier to debug and maintain if you called a function inside your loops:

if( NEXT){

for (var i:int = searchHit; i< array.length; i++) {

evalF(i);

} else {

for (i=searchHit; i>=0; i--){

evalF(i);

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 26, 2013 Jan 26, 2013

So it seems you have your results in a var named 'array'. At this point, for pagination, you  just need 2 'state' variables. 1, the amount of results to show per page. 2, the current page or index you're on.

e.g.

var resultsPerPage:int = 30;

var currentPage:int = 0; // start at 0 for array indexing

for (var i:int = (currentPage * resultsperPage); i < Math.min(array.length,(currentPage * resultsPerPage + resultsPerPage)); i++)

{

     // display results, array

}

When you hit next, validate if there's more results beyond the 'resultsPerPage' you're already showing. e.g. 50 results but showing 30 per page. On that you'll get 2 pages, one with 30, one with 20. So on that page the "Next" button should be disabled because there are no more pages beyond page 2. Vice versa for a "Previous" button. If your currentPage is 0 then you can't go back.

The logic of that loop is you take into account the page you're on, multiplied  by the number of results to show per page. The Math.min() will keep the loop within range of the total amount in array.length.

If, again, there's 50 results, it will check to see if the current page multiplied by results per that page in addition to the number of results on that page is valid. On page 2, with 50 total results and 30 results per page, that equation will be (1(page) * 30(results per page) + 30(results to show an entire new page)) is an acceptible value. It's not because it's 60 (1 * 30 = 30, 30 + 30 = 60) and you only have 50 results. The Math.min() saves you from choosing to loop that by by choosing instead array.length, which is 50. So your loop will go from the current page (30) to the array.length (50) showing 20 results.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 26, 2013 Jan 26, 2013

Geez - my description was terrible!!.  I forgot to mention that it's a datagrid for a desktop app, so pagination isn't an issue.  I did not mean to waste your time Sinious, but it's a pretty good description of pagination, so hopefully others looking for that will find it.

I'm going to set up the function within the loops like kGlad described.  I'll see if calling the function slows things down notciably rather than just having the loops contain their own identical loop data.  I do't think it will too much, but some grids will have 100 000 - 200 000 records.

Thanks guys

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 26, 2013 Jan 26, 2013

you're welcome.

you won't see a perceptible slow down until you loop through an order of magnitude in excess of 10**9 loops.  10**5 loops should require far less than .1 second unless you are doing some extensive string operations.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 26, 2013 Jan 26, 2013

10**9 !!!!!  Holy. 

That's good to know mate.  I'll stick with outsourcing a single function then.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 27, 2013 Jan 27, 2013

Just tossing in that huge loops with lots of bits of data sent to the function can have some performance difference by forcing the arguments to be an an Object.

To illustrate easily, native types like the int you are passing in to the function will force the function to make a local copy of the int and then return a value to be re-assigned. It will not make a reference. To prove it:

var myX:int = 10;

var myY:int = 20;

trace(myX + ", " + myY); // traces: 10, 20

addOneByInt(myX, myY);

trace(myX + ", " + myY); // traces: 10, 20

// int was not an object therefore a copy needed to be made, wasting creation

// and possibly re-assigment cpu cycles

function addOneByInt(xInt:int,yInt:int):void

{

     // just adds 1 to values passed

     xInt++;

     yInt++;

}

What happens is "xInt:int" and "yInt:int" are created at function scope with the value passed in the argument assigned to it, because it's a native (non-object) type.

Here's the difference. If you send an object, no copies need to be made, a direct refreence is made. On excessive amounts of loops this needless assignment can be avoided and should speed up your code.

e.g., Reference version:

var myObj:Object = {myX:10, myY:20};

trace(myObj.myX + ', ' + myObj.myY); // traces: 10, 20

addOneByObject(myObj);

trace(myObj.myX + ', ' + myObj.myY); // traces: 11, 21

// since an object was passed, references are used

function addOneByObject(myValues:Object):void

{

     // even though it's "myValues" and not "myObj" it's still

     // a memory speed reference that is actually affecting

     // the object reference passed "myObj"

     myValues.myX++;

     myValues.myY++;

}

If you have tons of records to loop over and want to use functions, try to use objects. Senting natives like 'int' causes copies and returning them requires reassignment when an object will be affected directly. The savings is seen with excessive loops and lots of values passed to the function.

Do not some caveats. Just because String is actually an Object, passing it won't be a reference. Array is also Object, and it WILL be passed as a reference. So knowing which will be passed as a reference will help.

You can read about this here:

http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f5...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 28, 2013 Jan 28, 2013

Thanks Sinious - I will see if the current set up is slow once everything is implemented, and if so, work on this.  Otherwise I'll wait until I've got the other major parts of the next update in place before tackling aspect.

Makes perfect sense though.  Cheers.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 28, 2013 Jan 28, 2013
LATEST

You're welcome and good luck!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines