Add Elements in Array in Inspector with alphabetical sorting

Hey guys,

I have a lot of elements to add to an array, and I wonder if there is a faster way than drag and drop each element in the inspector. I wan`t them in alphabetical order. I tried to select them all al drag them right in the array of the inspector, but it sorts them by a wierd manner. Is there a simple way of doing that, but sorting in alphabetical order ?

Thanks a lot !

Claude

FWIW, in case somebody else stumbles across this question as I did, here’s the solution I have settled on for now. In the script containing an array property, add a bit of code to create a contextual menu, like this:

[ContextMenu ("Sort Frames by Name")]
void DoSortFrames() {
    System.Array.Sort(frames, (a,b) => a.name.CompareTo(b.name));
    Debug.Log(gameObject.name + ".frames have been sorted alphabetically.");
}

In this example, I have a “public Sprite frames” property; just change all occurrences of “frames” to whatever your own array property is, and it ought to work. (Also, this is C#; changes would be needed for JavaScript.)

I like this solution because it goes right in the script with the array property, rather than needing a separate editor script. Also I much prefer letting the designer sort when they want to, rather than (say) sorting at runtime, which forces a requirement that your assets be named a certain way.

I’d rather something generic that could fix the problem across the board, but barring that, this is the next best thing.

As CHPedersen argues, having thise done automatically by Unity is a bad idea. Luckily Unity allows us to implement our own behavior to some extent.

You need to create either a [custom inspector][1] for your class, or create a [property drawer][2] if you have this behavior in multiple scripts. I would then make a button which, when pressed, sorts the list. Sorting the list every repaint or addition/removal seems terribly wasteful to me.

The next thing you need to do is implement a sorting algorithm. I would recommend the [Radix sort][3] (hint: use a dictionary in C#) for sorting strings. You can sort anything you can provide an enumeration for.

EDIT:

Because I assume you’ve already implemented the sorting functionality, I’ll show you how I did it, for reference:

MyBaseClass _target;
	
void OnEnable ()
{
	_target = (MyBaseClass)target;
}

private void SortArray(){
	string ordering = "abcdefghijklmnopqrstuvxyz ";
	Dictionary<char, List<string>> buckets = new Dictionary<char, List<string>>();
	string[] targetArray = _target.stringArray;
	List<string> tempList = new List<string>();
	int maxLength = -1;
	
	foreach(string s in targetArray){
		if(s.Length > maxLength)
			maxLength = s.Length;
	}
	
	//divide into buckets
	for(int character = maxLength-1; character>-1;character--){
		for(int i=0;i<targetArray.Length;i++){
			char currentChar;
			//an if-else -construct here would be more efficient, but I find this to be more illustrative
			try{
				currentChar = targetArray*[character];*
  •  	}catch (System.IndexOutOfRangeException e){*
    
  •  		currentChar = ' ';					*
    
  •  	}*
    
  •  	if(!buckets.ContainsKey(currentChar))*
    
  •  		buckets.Add(currentChar,new List<string>());*
    

_ buckets[currentChar].Add(targetArray*);_
_
}*_

* //combine buckets*
* for(int i=0;i<ordering.Length;i++){*
_ if(buckets.ContainsKey(ordering*)){
foreach(string s in buckets[ordering])
tempList.Add(s);
}
}*_

* targetArray = tempList.ToArray();*
* tempList.Clear();*
* buckets.Clear();*

* }*

* target.stringArray = targetArray;*
}
[1]: http://docs.unity3d.com/Documentation/ScriptReference/Editor.html*_
_[2]: http://docs.unity3d.com/Documentation/ScriptReference/PropertyDrawer.html*_

[3]: Radix sort - Wikipedia

The same thing annoyed me very much and I found a simple solution.

1) Make a public list

public List<YourType> Objects;

2) Make a class implementing IComparer

 class Comparer : IComparer<YourType>
    {
        int IComparer<YourType>.Compare(YourType a, YourType b)
        {
            if (a.ToString().Length < b.ToString().Length) return -1;
            else if (a.ToString().Length > b.ToString().Length) return 1;
            else return System.String.Compare(a.ToString(), b.ToString());
        }
    }

3) In the Start or Awake function:

 Comparer comparer = new Comparer();
 Objects.Sort(comparer);

4) Voila!

Your objects are sorted alphabetically. :slight_smile:

It would be easier to use a [Generic List][1] Instead of built in arrays and you can just call `_myList.Sort();` and it's sorted .

Here's an example

using UnityEngine ;
using System.Collections.Generic;

public class MyScript : MonoBehaviour  
{
    public List<string> _myList = new List<string>() ;

    // Use this for initialization
    void Start () 
    {
	    SortList();
    }
    void SortList () 
    {
	    _myList.Sort();
    }
}

Regards