Copy link to clipboard
Copied
I'm trying to sort out a way to search through nested layers for any layer starting with *, store them all to an array, and then use an array index to select the corresponding nested layer. I currently have a method that this works for but it feels inefficient and requires interations every time I try to access a nested layer and check for names. It seems like saving the entire path (app.activeDocument.layers[#].layers[#].getByName....) stored into the array would be the cleanest for working on the layer in the future however I can't seem to use the path once it goes into the array (app.activeDocument.activeLayer = path[0] for example does not work). Any help would be apprecaited.
1 Correct answer
to go through nested layers you need a "recursive" function, a function that calls itself, as pointed out in m1b's sample script above. So in short, your function will analyze the condition you're looking for then if it has sublayers, it calls itself with the layer as argument.
here's a sample
var idoc = app.activeDocument;
var layers = [];
collectLayers (idoc, layers);
alert(layers);
function collectLayers(container, layers) {
if(container.name.indexOf ('*') == 0)
layers.push(
...
Explore related tutorials & articles
Copy link to clipboard
Copied
Hi,
Perhaps you an just give the nested layer a unique name? Then just access it with:
var name = 'nested-layer-1'
var myNestedLayer = app.activeDocument.layers.getByName(name);
If you need an array of these nested layers for another script, then use a function to collect them all by that method. You don't need a path (as far as I can tell from reading your post)—the array just stores references to the actual layers.
If you're happy to post your script I'll be able to understand your needs better.
Copy link to clipboard
Copied
My understanding is that in order to refer to a nested layer I need to first refer to the parent layer. So to that end I don't think your example works as it would just work on the top most layers. I could be mistaken but I think I need to iterate over everything to go down in the heirarchy tree. So instead of:
...activeDocument.layers.getByName...
it would have to be
...activeDocument.layers[#].layers[#].getByName...
But this means extensive iteration and then lengthier code to access layers vs nested layers vs nested nested layers and so on.
Copy link to clipboard
Copied
You're right! I didn't know that.
I've written a couple of functions to help out. You seem to be familiar with scripting so see what you make of them:
// gets a layer by name
function getLayerByName(name) {
var layers = allLayers();
var found;
for (var i = 0; i < layers.length; i++) {
if (layers[i].name == name) {
found = layers[i];
break;
}
}
return found; // undefined if not found
}
// gets an array of every layer of active document
function allLayers(layers) {
// returns an array containing layers, including layers found inside layers
if (layers === undefined) layers = app.activeDocument.layers;
var found = [];
for (var i = 0; i < layers.length; i++) {
var sublayers = layers[i].layers;
if (sublayers.length > 0) {
found = found.concat(allLayers(sublayers));
}
}
found = found.concat(objectsIntoArray(layers));
return found;
}
// this moves the layers out of their "Layers" object and into an ordinary Array
function objectsIntoArray(objects) {
var array = [];
for (var i = 0; i < objects.length; i++) {
array.push(objects[i]);
}
return array;
}
Regards,
Mark
Copy link to clipboard
Copied
to go through nested layers you need a "recursive" function, a function that calls itself, as pointed out in m1b's sample script above. So in short, your function will analyze the condition you're looking for then if it has sublayers, it calls itself with the layer as argument.
here's a sample
var idoc = app.activeDocument;
var layers = [];
collectLayers (idoc, layers);
alert(layers);
function collectLayers(container, layers) {
if(container.name.indexOf ('*') == 0)
layers.push(container);
for (var b=0; b<container.layers.length; b++) {
collectLayers (container.layers[b], layers);
}
}
Copy link to clipboard
Copied
Nice! 🙂
Copy link to clipboard
Copied
That's great - thank you!
Copy link to clipboard
Copied
Developing a step further on this - how would you go about collecting the pathItems that exist within these flagged layers? I'm still learning about recursion so another pointer here would be great.
Copy link to clipboard
Copied
just follow the same concept. Add another array to hold the pathItems. Then when you evaluate each layer, if the condition is true, after adding the layer to the layer array, loop through its path items and add them one by one to the paths array.
var idoc = app.activeDocument;
var layers = [];
var paths = [];
collectLayers (idoc, layers);
alert(layers);
alert(paths);
function collectLayers(container, layers) {
if(container.name.indexOf ('*') == 0) {
layers.push(container);
for (var a=0; a<container.pathItems.length; a++)
paths.push(container.pathItems[a]);
}
for (var b=0; b<container.layers.length; b++) {
collectLayers (container.layers[b], layers);
}
}

