Skip to main content
Known Participant
November 8, 2024
Answered

How-to return boolean from array

  • November 8, 2024
  • 1 reply
  • 929 views

In this script that  moves layers with the same name I would like to include layers that are locked and hidden while maintaining their state once transferred. I am failing at retrieving the push value and using it as a boolean.

/--------------------------------------------------
// MergeLayers
//--------------------------------------------------
function MergeLayers() {
if (!documents.length) return;
var doc = app.activeDocument;
var layerGroups = collectSameLayers(doc);
moveLayersToNew(doc, layerGroups);
}

// Collect layers with the same name
function collectSameLayers(doc) {
var layerGroups = [];

for (var i = 0; i < doc.layers.length; i++) {
    var currLayer = doc.layers[i];
    var currName = currLayer.name;
    var isFound = false;
    var isLocked = false;
    var isVisible = true;

    if (currLayer.locked === true) {
        isLocked = [true];
        currLayer.locked = false;
    }

    if (currLayer.visible === false) {
        isVisible = [false];
        currLayer.visible = true;
    }

    for (var j = 0; j < layerGroups.length; j++) {
    if (layerGroups[j].name === currName) {
        layerGroups[j].layers.push(currLayer);
        isFound = true;
        break;
    }
    }
    if (!isFound) {
    layerGroups.push({name: currName,layers: [currLayer],lockStatus: [isLocked],visibleStatus: [isVisible]});
}
}
return layerGroups;
}

// Create new layer and move inside original layers
function moveLayersToNew(doc, layerGroups) {
for (var i = layerGroups.length - 1; i >= 0; i--) {
    var currGroup = layerGroups[i];

;    // Only process if there are multiple layers with the same name
    if (currGroup.layers.length > 1) {
    var newLayer = doc.layers.add();
    newLayer.name = currGroup.name;

    for (var j = currGroup.layers.length - 1; j >= 0; j--) {
        currGroup.layers[j].move(newLayer, ElementPlacement.INSIDE);


        // need help using the lockStatus and visibleStatus boolean from the layerGroups array
        currGroup.layers[j].locked =       
        currGroup.layers[j].visible = 
    }
    }
}
}

 

This topic has been closed for replies.
Correct answer jduncan

There were a few issues with the way you were trying to do things so I wrote some code to accomplish the task you are attempting.

 

A few things to note...

  • There are numerous ways to do this but I tried to follow your initial logic so you can understand the steps
  • There is no real need to store if a layer is locked or hidden since you can just check the property on the actual layer
  • The script below first groups similar layers by name, then does the work of moving them
var doc = app.activeDocument;
var groups = groupLayersByName();

// sanity check
for (var i = 0; i < groups.length; i++) {
  $.writeln(
    "Group " + (i + 1) + "\nName: " + groups[i][0].name + "\nCount: " + groups[i].length
  );
}

moveGroupedLayersToNewLayer(groups);

function groupLayersByName() {
  var groups = [];
  var group, cur, found, comp;
  // iterate over each layer
  for (var i = 0; i < doc.layers.length; i++) {
    cur = doc.layers[i];
    found = false;
    // iterate over groups of layer with same names
    for (var j = 0; j < groups.length; j++) {
      group = groups[j];
      comp = group[0];
      // check if the current layer name matches the group
      if (cur.name === comp.name) {
        found = true;
        group.push(cur);
        break;
      }
    }
    // if the current layer didn't match any groups create a new group
    if (!found) groups.push([cur]);
  }
  return groups;
}

function moveGroupedLayersToNewLayer(groups) {
  var group, commonName, parent, layer;
  // iterate over commong layer groups
  // please note the iteration is going in reverse to
  // try and keep the inital layer similar (not exact because of method)
  for (var i = groups.length - 1; i >= 0; i--) {
    group = groups[i];
    // skip groups with only one layer
    if (group.length === 1) continue;
    commonName = group[0].name;
    // create a new layer to hold common layers
    parent = doc.layers.add();
    parent.name = commonName;
    // iterate over common layer and move each into new parent layer
    // going in reverse again to keep layer order similar
    var locked, visible;
    for (var j = group.length - 1; j >= 0; j--) {
      layer = group[j];
      // get layer locked and visible status
      locked = layer.locked;
      visible = layer.visible;
      // unlock and make layer visible for move
      layer.locked = false;
      layer.visible = true;
      // move the layer into the parent layer
      layer.move(parent, ElementPlacement.INSIDE);
      // reset the layer locked and visible status
      layer.locked = locked;
      layer.visible = visible;
    }
  }
}

 

And, to answer your question about a boolean inside of an array, you can certainly store and retrieve a boolean value from an array. There were multiple reasons you were getting tripped up but about the boolean specifically, you were storing an array of an array of the boolean.

// you were doing something like
var isLocked = [false}
// then adding that to another array like
{...lockStatus: [isLocked]} // which really equals [[false]]
// so to access the boolean value you would need to go two levels deep
var boolValue = lockStatus[0][0]

 

1 reply

jduncan
Community Expert
jduncanCommunity ExpertCorrect answer
Community Expert
November 9, 2024

There were a few issues with the way you were trying to do things so I wrote some code to accomplish the task you are attempting.

 

A few things to note...

  • There are numerous ways to do this but I tried to follow your initial logic so you can understand the steps
  • There is no real need to store if a layer is locked or hidden since you can just check the property on the actual layer
  • The script below first groups similar layers by name, then does the work of moving them
var doc = app.activeDocument;
var groups = groupLayersByName();

// sanity check
for (var i = 0; i < groups.length; i++) {
  $.writeln(
    "Group " + (i + 1) + "\nName: " + groups[i][0].name + "\nCount: " + groups[i].length
  );
}

moveGroupedLayersToNewLayer(groups);

function groupLayersByName() {
  var groups = [];
  var group, cur, found, comp;
  // iterate over each layer
  for (var i = 0; i < doc.layers.length; i++) {
    cur = doc.layers[i];
    found = false;
    // iterate over groups of layer with same names
    for (var j = 0; j < groups.length; j++) {
      group = groups[j];
      comp = group[0];
      // check if the current layer name matches the group
      if (cur.name === comp.name) {
        found = true;
        group.push(cur);
        break;
      }
    }
    // if the current layer didn't match any groups create a new group
    if (!found) groups.push([cur]);
  }
  return groups;
}

function moveGroupedLayersToNewLayer(groups) {
  var group, commonName, parent, layer;
  // iterate over commong layer groups
  // please note the iteration is going in reverse to
  // try and keep the inital layer similar (not exact because of method)
  for (var i = groups.length - 1; i >= 0; i--) {
    group = groups[i];
    // skip groups with only one layer
    if (group.length === 1) continue;
    commonName = group[0].name;
    // create a new layer to hold common layers
    parent = doc.layers.add();
    parent.name = commonName;
    // iterate over common layer and move each into new parent layer
    // going in reverse again to keep layer order similar
    var locked, visible;
    for (var j = group.length - 1; j >= 0; j--) {
      layer = group[j];
      // get layer locked and visible status
      locked = layer.locked;
      visible = layer.visible;
      // unlock and make layer visible for move
      layer.locked = false;
      layer.visible = true;
      // move the layer into the parent layer
      layer.move(parent, ElementPlacement.INSIDE);
      // reset the layer locked and visible status
      layer.locked = locked;
      layer.visible = visible;
    }
  }
}

 

And, to answer your question about a boolean inside of an array, you can certainly store and retrieve a boolean value from an array. There were multiple reasons you were getting tripped up but about the boolean specifically, you were storing an array of an array of the boolean.

// you were doing something like
var isLocked = [false}
// then adding that to another array like
{...lockStatus: [isLocked]} // which really equals [[false]]
// so to access the boolean value you would need to go two levels deep
var boolValue = lockStatus[0][0]

 

nutradialAuthor
Known Participant
November 9, 2024

The only drawback that I noticed is that after you merge the layers .... if you had another instance where you created a new layer with the same name as that of one already merged, the previously merged sublayers become subsublayers.

nutradialAuthor
Known Participant
November 9, 2024

I'm not sure I follow... Are you running the script which "merges" common named layers then independently creating a new layer in the file with same common name as one of the groups, then running the script again? Could you share your file here as a pdf or even do a screen recording so I can follow your steps?


 

1 - Original layers with redundant names.

 

2 - After first merge ... perfect results.

 

3 - Created another layer with existing name.

 

4 - During second merge, as per highlight,

all sublayers get moved another level down.

 

This is not a big deal and it would be a highly unusual occurance. I do want to run this script as a workflow maintenance script and ideally I would leave the existing contents of the parent layer intact.