Search Unity

sort

Discussion in 'Scripting' started by peterbrinson, Feb 17, 2020.

  1. peterbrinson

    peterbrinson

    Joined:
    Jul 1, 2013
    Posts:
    63
    I want to sort a list, but it's a little complicated.

    I have a list (of type GameObject) in my class (MyLines) called, 'myWords'.
    Objects of this class, MyLines, are stored in an array 'LineInfo'

    Here's how they're declared:

    Code (CSharp):
    1. [System.Serializable]
    2.     public class MyLines
    3.     {
    4.         public GameObject theLineObject;
    5.         public List<GameObject> myWords;
    6.     }
    7.     public MyLines[] LineInfo;
    -------
    I want each example of the List 'myWords' (type GameObject) to be sorted based on x position, in ascending order.
    Because I have this List (myWords) buried in my class, I'm struggling to use OrderBy() for example.
    Thank you.
     
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    It's not really complicated if all you wanna do is sorting "myWords" by the position's x-value.

    There is already a Sort method for lists, actually multiple overloads. You can pass an actual type that implements the System.Collections.Generic.IComparer<T> interface, as well as one overload that takes a delegate of type System.Comparison<T>.

    The latter allows to simply throw in a lambda, if you don't need lots of boilerplate or "configurable" comparers.
    Here's an example, ascending & stable order:
    Code (csharp):
    1. myWords.Sort((lhs, rhs) => lhs.transform.position.x < rhs.transform.position.x ? -1 : 1);
    If lambdas scare you, you can move it to a separate method:
    Code (csharp):
    1.  
    2. // somewhere in your code
    3. myWords.Sort(SortByAscendingX);
    4.  
    5. private int SortByAscendingX(GameObject lhs, GameObject rhs)
    6. {
    7.     return lhs.transform.position.x < rhs.transform.position.x ? -1 : 1;
    8. }
    Here are the four variants:
    Code (CSharp):
    1. // ascending & stable
    2. _objs.Sort((lhs, rhs) => lhs.transform.position.x < rhs.transform.position.x ? -1 : 1);
    3.  
    4. // ascending & not stable
    5. _objs.Sort((lhs, rhs) => lhs.transform.position.x <= rhs.transform.position.x ? -1 : 1);
    6.  
    7.  
    8. // descending & stable
    9. _objs.Sort((lhs, rhs) => lhs.transform.position.x > rhs.transform.position.x ? -1 : 1);
    10.  
    11. // descending & not stable
    12. _objs.Sort((lhs, rhs) => lhs.transform.position.x >= rhs.transform.position.x ? -1 : 1);
     
    Last edited: Feb 18, 2020
  3. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    To avoid making unnecessary assumptions about the implementation details of Sort, you might want to use
    Code (CSharp):
    1. lhs.transform.position.x.CompareTo(rhs.transform.position.x)
    rather than something like
    Code (CSharp):
    1. lhs.transform.position.x < rhs.transform.position.x ? -1 : 1)
     
    orionsyndrome likes this.
  4. peterbrinson

    peterbrinson

    Joined:
    Jul 1, 2013
    Posts:
    63
    Thank you Suddoha. Wonderful.
     
  5. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,105
    I concur with Antistone.
    You can get ascending/descending simply by swapping places of lhs and rhs in his first example.
    Also you can very quickly extend any object by introducing a simple CompareTo method, and making it behave however crazy you want, just be returning -1 (less than), 1 (greater than), or 0 (same) according to some custom values or states.