Copy link to clipboard
Copied
I currently use a script that sorts object by number. However, it doesn't play nice when I have single, double, and triple digits within the same layer. Is there a way to modify this script so that when I run it, it will sort numbers accuratly?
1 Correct answer
Hi, here's how I would do it:
function sortLayerContentAlphanumerically() {
Array.prototype.forEach = function (callback) {
for (var i = 0; i < this.length; i++)
callback(this[i], i, this);
};
var layer = app.activeDocument.activeLayer;
var items = []
for (var i = 0; i < layer.pageItems.length; i++)
items.push(layer.pageItems[i])
items.sort(function (a, b) {
if (a.name.length === b.name.length) return a.name.localeCompare(b.name)
...
Explore related tutorials & articles
Copy link to clipboard
Copied
Hi, here's how I would do it:
function sortLayerContentAlphanumerically() {
Array.prototype.forEach = function (callback) {
for (var i = 0; i < this.length; i++)
callback(this[i], i, this);
};
var layer = app.activeDocument.activeLayer;
var items = []
for (var i = 0; i < layer.pageItems.length; i++)
items.push(layer.pageItems[i])
items.sort(function (a, b) {
if (a.name.length === b.name.length) return a.name.localeCompare(b.name)
else if (a.name.length < b.name.length) return -1
else if (a.name.length > b.name.length) return 1;
})
items.forEach(function (item) {
item.move(layer, ElementPlacement.PLACEATEND)
})
}
sortLayerContentAlphanumerically();
If you want your original function to work, then you'd just need to expand on .sort(). By default this returns alphanumerically by the first digit, but you'd need to do something similar to my own sort function where I look at each object (a + b) and return either 1, 0, or -1 so it knows to place it before or after. We know that any thing with 3 digits is greater than anything with 2, so always return either -1 or 1 in this instance, but if each object has the same digits we're free to sort them through a String.prototype.localeCompare (which itself returns numeric values like 1, 0, or -1).
Bear in mind this assumes all objects are strictly numerically named. You could pretty easily modify it so it handles things like "Layer 29" or "Item 28", etc., but given your current file I didn't feel like that would be needed.
Copy link to clipboard
Copied
This is great, thank you!
I do sometimes have to use letters either before or after, ie A201, B201, or 208A, 208B. Does this script work for that, or would it goof it up? It never gets much more complex than that.
Copy link to clipboard
Copied
Hi, it would be easy to work that in. Try this one instead, which uses Regex to extract the number from the layer name and compares only the numeric digits:
function sortLayerContentAlphanumerically() {
Array.prototype.forEach = function (callback) {
for (var i = 0; i < this.length; i++)
callback(this[i], i, this);
};
var layer = app.activeDocument.activeLayer, items = [];
for (var i = 0; i < layer.pageItems.length; i++)
items.push(layer.pageItems[i])
items.sort(function (a, b) {
if (/\d/.test(a.name) && /\d/.test(b.name)) {
var aNum = a.name.match(/\d{1,}/)[0], bNum = b.name.match(/\d{1,}/)[0]
if (aNum.length === bNum.length) return aNum.localeCompare(bNum)
else if (Number(aNum) < Number(bNum)) return -1
else if (Number(aNum) > Number(bNum)) return 1;
} else return -1;
})
items.forEach(function (item) {
item.move(layer, ElementPlacement.PLACEATEND)
})
}
sortLayerContentAlphanumerically();
This should work for anything that has "a20" or "barrel8", but not two sets of digits like "Layer 20 Copy 39", etc.
Copy link to clipboard
Copied
This is incredibly helpful, and I really appreciate your help.
I was testing the script and I came across a somewhat fringe case where I have two of the same numbers with different letters. i.e. 2A, 2B, 3A, 3B, 4A, 4B. Luckily it's rather rare and few enough that it's not terribly time consuming to just manually adjust the ones that fall out of order. Typically the letters come before the numbers, but not always.
Would it be difficult to add in a way to have it sort these in that manner as well? I attached a picture of a test case after running the script.
Copy link to clipboard
Copied
Sure, can you post a list of all possible names and their intended order?
Copy link to clipboard
Copied
https://docs.google.com/spreadsheets/d/1l7i-KyV8CfUgJTPrkSNmX5wiuRO5I0SiUlkgoVuv8uY/edit?usp=sharing
Here's a link to a spreadsheet I've been using for testing. This is an extreme example, but it's in the order that would be needed. For the duplicate numbers that have different letters, which I've marked with green, they could be in the order I have them now (A16, A17, ..., B16, B17, ...) or they could be done like this: A16, B16, A17, B17, ect. Whatever is easiest that doesn't mess other things up.
I recognize that something like this can get pretty tricky, sorting has been a real thorn for what I've been doing.

