Skip to main content
Known Participant
November 8, 2024
Answered

How-to return boolean from array

  • November 8, 2024
  • 1 reply
  • 913 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

Thanks so much brother ... specially for the explanation which now makes total sense. The code that you wrote in it of itself teaches me a lot as well. I'm new to arrays and I tried [0] to no end.