Skip to main content
Obi-wan Kenobi
Legend
March 15, 2017
Question

Code to be evaluated! [017] Double loop! …

  • March 15, 2017
  • 1 reply
  • 774 views

Hi Scripters,

Even if this seems to work, should I avoid this kind of writing? [line 20]

• Double loop while + for on the same "F"

• Find/Replace without "changeTo"

[ Original thread here:  Repeated Volume Numbers in Index  ]

redraw = app.scriptPreferences.enableRedraw; 

app.scriptPreferences.enableRedraw = 0;

app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.ENTIRE_SCRIPT, "FindReplace! …");

app.scriptPreferences.enableRedraw = redraw; 

function main()    

    {

        var myDoc = app.activeDocument,

        FindWhat1 = "(I+:\\h)(\\d+(,\\h)?)+\\K\\1",

        FindWhat2 = "\\d+\\K,(?=\\hI+:\\h)",  ReplaceBy2 = ";";

        app.findGrepPreferences = app.changeGrepPreferences = null;

        app.findGrepPreferences.findWhat = FindWhat1;

        myFound = myDoc.findGrep();

        var F = myFound.length;

        while (F--) for (var f = 0; f < F; f++) myDoc.changeGrep();

        app.findGrepPreferences = app.changeGrepPreferences = null;

        app.findGrepPreferences.findWhat = FindWhat2;

        app.changeGrepPreferences.changeTo = ReplaceBy2;

        myDoc.changeGrep();

        app.findGrepPreferences = app.changeGrepPreferences = null;

    }

Thanks in advance! 

(^/)

This topic has been closed for replies.

1 reply

Loic.Aigon
Legend
March 15, 2017

Even before considering code optimiation, I am troubled with the intention:

Line 20:

while (F--) for (var f = 0; f < F; f++) myDoc.changeGrep();

Ok so you want to loop through fingGrep results and do change. But myDoc.changeGrep() is global. So you are just processing teh whole doc over and over.

don't loop and just call myDoc.changeGrep() or if loop, prefer myFound.changeGrep();

Plus, you are actually changing to nothing as change option are null (line 16) and not redefined.

Also you are "doing" the same thing twice. Set a F/C function and call it twice with a different set of properties.

Loic.Aigon
Legend
March 15, 2017

 

 

app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.ENTIRE_SCRIPT, "FindReplace! …"); 

 

 

 

function main()      

    { 

  var sps = app.scriptPreferences.properties,

  myDoc = app.properties.activeDocument, 

  fgp = app.findGrepPreferences.properties,

  cgp = app.changeGrepPreferences.properties; 

  if( !myDoc ) return;

   

  app.scriptPreferences.enableRedraw = false; 

  app.findGrepPreferences = app.changeGrepPreferences = null; 

  changeGrep ( myDoc, {

  find :  {

  findWhat:"(I+:\\h)(\\d+(,\\h)?)+\\K\\1"

  },

  change : {

  // ????

  }

  });

  changeGrep ( myDoc, {

  find :  {

  findWhat:"\\d+\\K,(?=\\hI+:\\h)"

  },

  change : {

  changeTo:";"

  }

  });

  app.findGrepPreferences.properties = fgp;

  app.changeGrepPreferences.properties = cgp; 

  app.scriptPreferences.properties = sps;

    } 

function changeGrep(doc, props ) {

  app.findGrepPreferences.properties = props.find;

  app.changeGrepPreferences.properties = props.change;

  doc.changeGrep();

}

FWIW

Loïc

Ozalto | Productivity Oriented - Loïc Aigon

Obi-wan Kenobi
Legend
March 15, 2017

Hi Loïc,

Thanks for your comments!

To be more explicite! …

I use 2 regex!

If I only used the ID Find/Replace window, I should need to play 4 times the first and 2 times the second to have a "zero" replace-counter:

Regex1:

Regex2:

… So, if you count the points, we have: (Regex1: 50 + 20 + 10 + 0) + (Regex2: 20 + 0) = 80 find/replace!

I've rewritten the script! My deal is to launch "x" times the regex1 because I know it won't find all the occurrences in one time!

So:

function main()    

    {

        var myDoc = app.activeDocument,

        FindWhat1 = "(I+:\\h)(\\d+(,\\h)?)+\\K\\1",

        FindWhat2 = "\\d+\\K,(?=\\hI+:\\h)",  ReplaceBy2 = ";";

        app.findGrepPreferences = app.changeGrepPreferences = null;

        app.findGrepPreferences.findWhat = FindWhat1;

        myFound = myDoc.findGrep();

        var F = myFound.length,

        myCounter = 0;

        for (var f = 0; f < F; f++) {

            myChange1 = myDoc.changeGrep();

            F = myChange1.length;

            myCounter += F;

        }

        app.findGrepPreferences = app.changeGrepPreferences = null;

        app.findGrepPreferences.findWhat = FindWhat2;

        app.changeGrepPreferences.changeTo = ReplaceBy2;

        myChange2 = myDoc.changeGrep();

        app.findGrepPreferences = app.changeGrepPreferences = null;

        myCounter += myChange2;

        alert( "Counter:  "+ myCounter + " treated!  (^/) ;-)" )

    }

What I'm trying to get is having a first estimation of "F", run  x (<= F) times the regex1 [see lines 07 + 14].

When "F" will be equal to 0 [see line 13], the "for" loop will be finished and, so, the "while" loop will be finished too!!

At this moment, the script could run the Regex2!

As you see, this 2nd version works but surely a more orthodox way, based on these 2 regex! 

Of course, I could use Multi-Find/change and do it directly with a 30-seconds work but it's not the problematic!

(^/)