Sorting app.documents

Discussion of Photoshop Scripting, Photoshop Actions and Photoshop Automation in General

Moderators: Tom, Kukurykus

mike

Sorting app.documents

Post by mike »

How do I sort the app.documents object by the psd names?

eg.

Code: Select allinputFiles = app.documents;

// inputFiles[0].name = "filename2.psd"
// inputFiles[1].name = "filename1.psd"
// app.documents is ordered in the order you opened psds (which isn't always alphanumeric)

// if i change inputFiles to this: inputFiles = Array('b.psd', 'c.psd', 'a.psd') -- the sort method below works... however when I try to sort the object itself it breaks...

 inputFiles.sort(  function (a, b) {
                                                      function chunkify(t) {
                                                        var tz = new Array();
                                                        var x = 0, y = -1, n = 0, i, j;

                                                        while (i = (j = t.charAt(x++)).charCodeAt(0)) {
                                                          var m = (i == 46 || (i >=48 && i <= 57));
                                                          if (m !== n) {
                                                            tz[++y] = "";
                                                            n = m;
                                                          }
                                                          tz[y] += j;
                                                        }
                                                        return tz;
                                                      }

                                                      var aa = chunkify(a.toLowerCase()); //even if i change this to a.name.toLowerCase() - it still doesn't work
                                                      var bb = chunkify(b.toLowerCase()); //even if i change this to b.name.toLowerCase() - it still doesn't work

                                                      for (x = 0; aa[x] && bb[x]; x++) {
                                                        if (aa[x] !== bb[x]) {
                                                          var c = Number(aa[x]), d = Number(bb[x]);
                                                          if (c == aa[x] && d == bb[x]) {
                                                            return c - d;
                                                          } else return (aa[x] > bb[x]) ? 1 : -1;
                                                        }
                                                      }
                                                      return aa.length - bb.length;
                                                    }
                                        );

xbytor

Sorting app.documents

Post by xbytor »

Code: Select allvar appList = // make a copy of app.documents as a proper Array. app.documents.slice(0) will probably not work.

function sortByName(ary) {
  function nameCmp(a, b) {
    // add toLowerCase calls here if required
    if (a.name < b.name) {
      return -1;
    } else if (a.name > b.name) {
      return 1;
    }
    return 0;
  }

  return ary.sort(nameCmp);
};

sortByName(appList);
mike

Sorting app.documents

Post by mike »

Thanks for replying xbytor. Few things - it looks like you forgot to add how I get the appList?

var appList = // make a copy of app.documents as a proper Array. app.documents.slice(0) will probably not work.

Also later in my script I'm setting the activeDocument to an inputFile in a for loop (which may already be open but not the activeDocuement...hence me setting it as active)

Code: Select allapp.activeDocument = inputFiles[iii]; //this works and set the active doc as the next input file (which may already be open)

How would i do that with a regular array and not a document object?
xbytor

Sorting app.documents

Post by xbytor »

appList as an array. Copy the docs in app.documents to that appList the sort it.
mike

Sorting app.documents

Post by mike »

I'm not sure what you mean?

Do you mean create a loop that makes a new array that contains only the string name:
Code: Select allloop (i++){
   newArray(i) = activeDoc(i).name;
}

I've tried that and it works however the problem is I still need to be able to set the activeDoc to inputFiles and also get the path, eg. inputFiles.path. I'm also opening files this way too: Code: Select allopen( File(inputFiles) ); None of which I would be able to do with just a string array.

Is there any way I can sort the app.documents object by .name?
Mike Hale

Sorting app.documents

Post by Mike Hale »

Not sure what you mean. app.documents is read-only so you can't sort it directly. It is also what Adobe calls a collection and not an array so even if it wasn't read-only you couldn't sort it like a normal array.

So like xbytor suggested you made a new array and use the documents collection to populate the elements. You can then sort that array however you like. If you use the function x posted you can sort by name. You can then use that sorted array to switch document. Just remember it will not update if you add or close a document.

But it will be an array of document objects. You sill will not be able to use it with app.open. You need a valid file object for that( and why are you trying to open an already open document )
Code: Select allvar aNewArray = [];
for(var docIndex=0;docIndex<app.documents.length;docIndex++){
    aNewArray.push(app.documents[docIndex]);
 }
sortByName(aNewArray);
app.activeDocument = aNewArray[0];



function sortByName(ary) {
  function nameCmp(a, b) {
    // add toLowerCase calls here if required
    if (a.name < b.name) {
      return -1;
    } else if (a.name > b.name) {
      return 1;
    }
    return 0;
  }

  return ary.sort(nameCmp);
};
mike

Sorting app.documents

Post by mike »

Thank you guys! This board is so helpful!

The code works perfectly! I just had to change the sort so it ordered the files naturally. So instead of sorting like: a.psd, b10.psd, b1.psd, b2.psd it sorts a.psd, b1.psd, b2.psd, b10.psd.

If anyone needs that sort:
Code: Select allvar inputFiles = [];
                                        for(var docIndex=0;docIndex<app.documents.length;docIndex++){
                                            inputFiles.push(app.documents[docIndex]);
                                         }
                                                                               
                                        //sort all opened files by filename / do this so when i export and # each one they export in the right order
                                        inputFiles.sort(function (a, b) {
                                                  function chunkify(t) {
                                                    var tz = new Array();
                                                    var x = 0, y = -1, n = 0, i, j;

                                                    while (i = (j = t.charAt(x++)).charCodeAt(0)) {
                                                      var m = (i == 46 || (i >=48 && i <= 57));
                                                      if (m !== n) {
                                                        tz[++y] = "";
                                                        n = m;
                                                      }
                                                      tz[y] += j;
                                                    }
                                                    return tz;
                                                  }

                                                  var aa = chunkify(a.name.toLowerCase());
                                                  var bb = chunkify(b.name.toLowerCase());

                                                  for (x = 0; aa[x] && bb[x]; x++) {
                                                    if (aa[x] !== bb[x]) {
                                                      var c = Number(aa[x]), d = Number(bb[x]);
                                                      if (c == aa[x] && d == bb[x]) {
                                                        return c - d;
                                                      } else return (aa[x] > bb[x]) ? 1 : -1;
                                                    }
                                                  }
                                                  return aa.length - bb.length;
                                                }
                                            ); //sort */

                                                       
undavide

Sorting app.documents

Post by undavide »

Mike,
the chunkify() function has earned a place in my snippets library
Thanks,

Davide