How to sort objects alphabetically (inside of a layer)?

New Here ,
Sep 23, 2014 Sep 23, 2014

Copy link to clipboard

Copied

How to sort objects alphabetically (inside of a layer) on layer list?

I have already tried scripts for Layer sorting. They work indeed for the layers, but not the objects themselves packed inside.

TOPICS
Scripting

Views

17.9K

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Sep 23, 2014 Sep 23, 2014

Copy link to clipboard

Copied

post your script, someone will help you tweak it to work with the objects instead of layers,

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 23, 2014 Sep 23, 2014

Copy link to clipboard

Copied

It is not my script, but it works with layers. I found it googling some time ago.

#target "Illustrator" 

  

/*

     sort layers (with sublayer)

*/ 

  

var doc = app.documents[0]; 

var lay = doc.layers; 

var array_primary = []; 

for (var i=0, iL=lay.length; i < iL ; i++) { 

     if (lay.layers.length === 0) { 

          array_primary.push( lay.name ); 

     } 

     else { 

          array_primary.push( lay.name ); 

          var array_secondary = []; 

          for (var j=0, jL=lay.layers.length; j < jL ; j++) { 

           array_secondary.push(lay.layers.name); 

          }; 

          var result2 = array_secondary.sort( function (a,b) { return a > b }); 

          // sort sublayers 

          sort_layer (lay, result2); 

     } 

}; 

var result1 = array_primary.sort( function(a,b) { return a > b } ); 

  

// sort layers 

sort_layer (doc, result1); 

  

function sort_layer (obj, array) { 

     for (var ri=0, riL=array.length; ri < riL ; ri++) { 

          obj.layers.getByName(array[ri]).zOrder( ZOrderMethod.SENDTOBACK ); 

     }; 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

Likewise, I'm interested to see if this can be resolved. The script I've been attempting to use is this: Click Here

Basically what I'm trying to achieve is a layer group by state, then by provider, then by city, then the dot representing the city.

Example:

  • Wyoming
    • Charter
      • Cable
        • Gillette, WY
        • Albin, WY
        • Additional Cities +

That above script so far will sort everything except the final (deepest) layer, the one with the object (my dot).

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

do you know how many "layers" in the hierarchy there will be? or is that an unknown value? for example.. the "Town, WY" always be under "cable" which will always be under "charter" etc? or is it possible that there could be more or less levels within the hierarchy?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

williamadowling wrote:

do you know how many "layers" in the hierarchy there will be? or is that an unknown value? for example.. the "Town, WY" always be under "cable" which will always be under "charter" etc? or is it possible that there could be more or less levels within the hierarchy?

Thanks for the reply,

Unfortunately the hierarchy is different. I'll give you a couple examples:

  • Wyoming
    • ACT
      • Fiber
        • Newcastle, WY
        • Sundance, WY
        • Gillette, WY
        • Casper, WY
        • (more beyond this, 18 cities total)
    • Charter
      • Cable
        • Jackson, WY
        • Riverton, WY
        • Gillette, WY
        • Casper, WY
        • (more beyond this, 24 cities total)
    • CenturyLink
      • DSL
        • Gillette, WY
        • Casper, WY
        • (more beyond this, 34 cities total)
      • T1
        • Gillette, WY
        • Casper, WY
        • (more beyond this, well over 100 cities total)
      • Fiber
        • Gillette, WY
        • (more beyond this, 50+ cities)

I hope this helps out. If there is some way to sort each of these objects underneath their layers with one script, and it needs to be modified to account for the amount of layers I can do that, I just don't know how to write the script.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

great. the name of the layers in the hierarchy don't matter so much. i just needed to know if they were going to go any deeper. is it at all possible that there could be a separate layer inside of, for example, cable? or is that as deep as it could go?

i'll assume that it can't.. because i don't know why one town/city would act as a group, based on this model. let me put together the basic nested loop structure. i don't actually know the syntax for alphabetizing, but i'll indicate where that code should go within your loops.

**EDIT**

the city/town part. are those groups or paths? do you have a screenshot of the actual layers panel expanded such as your example you typed out? that would help.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

Awesome, The cities are the deepest layer/object there is. There isn't anything below the cities, and the cities them selves are just a circle with a solid gold fill (object). To answer your question if there were any more layers beneath the "service type," for example, cable, the answer is no. In the examples I gave above, that is the exact structure/hierarchy, except some companies (CenturyLink) offer multiple service types, so they have more than one layer there, but the cities contained in each layer is still the bottom level.

I've attached a screen shot of what it looks like, because unfortunately I do not know what the "dots" actually are.

screencap.png

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

perfect. thanks. almost finished. = )

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

So this is your looping structure. i'm not saying it's the BEST way to do it.. i'm sure there's some advanced way that is much cleaner than i've made this. But this will dig you all the way into your citys/towns objects.

function alphabetize(){

  if (app.documents.length > 0){

  var docRef = app.activeDocument;

  var state = docRef.layers;

  for (a = 0; a < state.length; a++){ // loop through your states

  var  provider = state.groupItems;

  if (provider.length > 0){

  for (b = 0; b < provider.length; b++){ // loop through providers

  var product = provider.groupItems;

  if (product.length > 0){

  for (c = 0; c < product.length; c++){ // loop through products

  var town = product.pathItems;

  if (town.length > 0){

  for (d = 0; d < town.length; d ++){ // loop through towns

  //alphatbetization code goes here

  } // end for loop D

  } // end if exists town

  } // end for loop C

  } // end if exists product

  } // end for loop B

  } // end if exists top groups

  } // end for loop A

  } // end if document exist

  else{

  alert ("No document Open");

  } // end else no document open

  } // end function

alphabetize();

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

Do I need to have anything selected for this script to work? When I'm running it I'm not seeing anything changing.

*** EDIT ***

So this is the alphabetization code I'm trying to use, but my guess is it's incorrect:

sort_layer (docRef, result1);

function sort_layer (obj, array) {

  for (var ri=0, riL=array.length; ri < riL ; ri++) {

  obj.layers.getByName(array[ri]).zOrder( ZOrderMethod.SENDTOBACK );

  };

}

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

this script doesn't actually DO anything. it's just getting you inside the layers to the level you want. like i said i don't know how to actually alphabetize... i can think of a way, but i KNOW it's not the right way because it's really clunky and verbose. and if i'm honest, i can't really see what's doing the alphabetization in the script that you posted. i'll see what i can find out. i'm all about learning how to do this too.

further information. this script doesn't actually act upon objects. only modifies their indexes in the layers panel. therefore, no selection is necessary and having any/some/all objects selected will not affect the outcome..

let me see what i can do about alphabetizing

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

I see... Well I apologize I'm not more help as I barely understand this script.

I've found another array for alphabetizing, would this help in any manner?

var layers = activeDocument.layers;

var layersArray = [];

var len = layers.length;

// store all layers in an array

for (var i = 0; i < len; i++) {

layersArray.push(layers);

}

// sort layer top to bottom

layersArray.sort();

for (i = 0; i < len; i++) {

layersArray.move(layers, ElementPlacement.PLACEBEFORE);

}

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

i figured it out actually. much easier than i imagined. i'm finishing up now.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

hmm.. i'm perplexed.. here's what i got.. it is indeed alphabetizing the objects.. but it is NOT changing the position of the layers.. for some reason.

i think it's because it's outside the "d" for loop, but idk.. anybody out there that's smarter than I care to help out??

function alphabetize(){

  if (app.documents.length > 0){

  var docRef = app.activeDocument;

  var state = docRef.layers;

  for (a = 0; a < state.length; a++){ // loop through your states

  var  provider = state.groupItems;

  if (provider.length > 0){

  for (b = 0; b < provider.length; b++){ // loop through providers

  var product = provider.groupItems;

  if (product.length > 0){

  for (c = 0; c < product.length; c++){ // loop through products

  var town = product.pathItems;

  if (town.length > 0){

  var townList = [];

  for (d = 0; d < town.length; d ++){ // loop through towns

  townList.push(town.name);

  } // end for loop D

  townList.sort();

  for (e = 0; e > townList.length; e++){ // re-order towns by name

  town.zOrder(ZOrderMethod.SENDTOBACK);

  alert(towns);

  } // end for loop E

  } // end if exists town

  } // end for loop C

  } // end if exists product

  } // end for loop B

  } // end if exists providers

  } // end for loop A

  } // end if document exist

  else{

  alert ("No document Open");

  } // end else no document open

  } // end function

alphabetize();

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

I showed this script to a co-worker and he provided me with some insight.

"it looks to me like when sorting townList you end up losing your indexed association with the 'town' array. So you must store the index of the town along with the name of the town; then sort by the name while still keeping a hold of what index it is in `town`."


He was able to give me a script back that accomplished what he recommended, but it still didn't quite work.

We compared his script, that was based off yours, and then compared and stole things from the original script that was sorting the layers themselves (see original code above) but not the path items.

We then put everything together and got it working with this!

#target "Illustrator"

function alphabetize()

{

     if (app.documents.length == 0)

     {

          alert("No document Open");

          return;

     }

     var docRef = app.documents[0];

     var state = docRef.layers;

     for (a = 0; a < state.length; a++)

     {

          var provider = state.layers;

          for (b = 0; b < provider.length; b++)

          {

               var product = provider.layers;

               for (c = 0; c < product.length; c++)

               {  

                    var town = product.pathItems;

                    if (town.length > 0)

                    {

                         var townList = [];

                         for (d = 0; d < town.length; d++)

                         { 

                              townList.push(town.name);

                         }

                         townList.sort();

                         sort_layer(product, townList);

                    }

               }

          }

     }

}

function sort_layer (obj, array) {

     for (var ri=0, riL=array.length; ri < riL ; ri++) {

     obj.pathItems.getByName(array[ri]).zOrder( ZOrderMethod.SENDTOBACK );

     };

}

alphabetize();

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jan 13, 2015 Jan 13, 2015

Copy link to clipboard

Copied

captainfodder schrieb:

… I've found another array for alphabetizing, would this help in any manner? …

Hi captainfodder,

the method sort() is not the best for all things. But it's the easiest way for simple sorting.

And if only path items in the layers exists, you can rebuild this snippet e.g. like that:

var layers = activeDocument.layers;

var objArray = [];

// this is now for the topmost layer only

// add a loop through all layers

var layPI = layers[0].pathItems;

var len = layPI.length; 

// store all layer items in an array

for (var i = 0; i < len; i++) {

    objArray.push(layPI);

    }

// sort layer top to bottom

objArray.sort();

for (i = 0; i < len; i++) {

    objArray.move(layPI, ElementPlacement.PLACEBEFORE);

    } 

Have fun

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 23, 2015 Sep 23, 2015

Copy link to clipboard

Copied

#target "Illustrator"

var doc            = app.activeDocument;

var Top_all_layers  = doc.layers;

Arrange_Layers(doc, Top_all_layers) ;

redraw();

function Arrange_Layers(where, T_Layers_OBJ) {

    var temp_L_names = new Array();

  

    for ( var i = 0 ; i < T_Layers_OBJ.length ; i++ ) {

        temp_L_names.push(T_Layers_OBJ.name);

    }

    sort_layer(where, temp_L_names.sort(naturalCompare)) ;;

    for ( var i = 0 ; i < T_Layers_OBJ.length ; i++ ) {

        if ( T_Layers_OBJ.layers.length != 0 ) {

            Arrange_Layers(T_Layers_OBJ, T_Layers_OBJ.layers) ;

        }

    }

return ;

}

function sort_layer(where, Layers_Array) {

  

    var temp_P_names  = Array() ;

    var Sorted_temp_P = Array() ;

  

    for (var k=0 ; k < Layers_Array.length ; k++) {

        var temp_layer = where.layers.getByName(Layers_Array) ;//

        var status_Lock = temp_layer.locked;

        var status_Preview = temp_layer.preview;

        var status_visible = temp_layer.visible;

      

        temp_layer.locked  = false;

        temp_layer.preview  = true;

        temp_layer.visible  = true;

        temp_layer.zOrder( ZOrderMethod.SENDTOBACK );

      

        temp_layer.locked  = status_Lock;

        temp_layer.preview  = status_Preview;

        temp_layer.visible  = status_visible;

    }

  

    for (var k=0 ; k < Layers_Array.length ; k++) {

      

        var temp_layer = where.layers.getByName(Layers_Array) ;//

        var temp_items = temp_layer.pageItems ;

      

        for (var l=0 ; l < temp_items.length ; l++) {

            temp_P_names.push(temp_items.name) ;

          

        }

  

        Sorted_temp_P = temp_P_names.sort(naturalCompare) ;

      

        try {

            for (var l=0 ; l < Sorted_temp_P.length; l++){

                $.writeln(Sorted_temp_P,"--", temp_items) ;

                var temp_OBJ = temp_layer.pageItems.getByName(Sorted_temp_P) ;          

                temp_OBJ.zOrder(ZOrderMethod.SENDTOBACK);

                //

            } //

        }

        catch (e)

        {

            //alert(e);

        }

      

    }

  

//

}

//

//

function naturalCompare(a, b) {

    var ax = [], bx = [];

    a.replace(/(\d+)|(\D+)/g, function(_, $1, $2) { ax.push([$1 || Infinity, $2 || ""]) });

    b.replace(/(\d+)|(\D+)/g, function(_, $1, $2) { bx.push([$1 || Infinity, $2 || ""]) });

  

    while(ax.length && bx.length) {

        var an = ax.shift();

        var bn = bx.shift();

        var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);

        if(nn) return nn;

    }

    return ax.length - bx.length;

}

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jun 12, 2017 Jun 12, 2017

Copy link to clipboard

Copied

Works great for me!

Script debugging window keeps appearing though. Is it because of the catch(e)? Or did I name it wrong and it is a .jsx and not a .js?

Thanks again!!

EDIT: Never mind, I found it!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 18, 2018 Sep 18, 2018

Copy link to clipboard

Copied

@Jung K Kwon - This is the first script I've ever tried with Illustrator (never had reason to try before), and it worked for me! I have a set of circles representing cities on a map, and they are named with state abbr. followed by city. E.g.

CA, Los Angeles
LA, New Orleans
TX, Houston
Thanks for posting the script!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 28, 2022 Apr 28, 2022

Copy link to clipboard

Copied

LATEST

numand49537644_0-1651205036831.png

I keep getting this error. Any help?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines