none
How to sort ArrayList in descending order based on frequency

    Question

  • Hi,

    I have an ArrayList with the following items:

    IAH:2, JFK:3, CDG:1, BLQ:1

    How would I sort this on descending order based on the numbers appearing after ':'.  The desired outcome should be:

    JFK:3  IAH:2, BLQ:1, CDG:1

    Appreciate any response.


    Marilyn Gambone

    Tuesday, June 25, 2013 5:24 AM

Answers

  • Since Array.Sort does not work with ArrayList, then use Sort which is a member of ArrayList: http://msdn.microsoft.com/en-us/library/0e743hdt.aspx.

    Consider the LINQ-based approach as well:

    var q = freqList.OfType<String>().OrderByDescending( s => int.Parse( s.Substring( s.LastIndexOf( ':' ) + 1 ) ) );

    Then call q.ToArray() or q.ToList() to obtain a typed array or list. By the way, modern generic collections like List<String> or List<MyItem> seems to be more suitable than collections of Objects.


    • Edited by Viorel_MVP Tuesday, June 25, 2013 6:37 PM ----
    • Marked as answer by deskcheck1 Tuesday, June 25, 2013 8:15 PM
    Tuesday, June 25, 2013 6:36 PM

All replies

  • There are a few different ways to do it.

    One example would be to create an IComparer to handle the sorting (which makes it easy to do the sorting in whatever mysterious ways you'd like).

            private class MyListComparer : IComparer<string>
            {
                public int Compare(string l, string r)
                {
                    string ls = l.Substring(l.LastIndexOf(':'), l.Length - l.LastIndexOf(':'));
                    string rs = r.Substring(r.LastIndexOf(':'), r.Length - r.LastIndexOf(':'));
    
                    return rs.CompareTo(ls);
                }
            }

    And then you can call it like so:

    Array.Sort(input, new MyListComparer());

    ICompare is in the System.Collections.Generic namespace.

    • Proposed as answer by cheong00 Tuesday, June 25, 2013 6:43 AM
    Tuesday, June 25, 2013 6:41 AM
  • I would have used string ls = l.Split(':')[1]; instead, though.
    Tuesday, June 25, 2013 6:45 AM
  • Yes, that makes it a lot neater. Very good suggestion!

    Tuesday, June 25, 2013 6:47 AM
  • Hi,

    I think this class works; my input array is somehow messed up.  Array.Sort requires a string[] array.

    So I converted my ArrayList to a string[] array.  I used StringBuilder to loop through my ArrayList and used an AppendFormat so I can add an empty string to later split it and create a string[] array.

    Problem is, even though I trimmed the last character from the Strinbuilder, when I convert it to a string[] array, an empty element is added.  This is causing an exception in the Comparer class since it's saying that it can't compare an empty element with another element.

    Here's the ArrayList to string[] code:

    ArrayList freqList = new ArrayList();

    freqList.Add("BLQ:1");
    freqList.Add("CDG:1");
    freqList.Add("IAH:2");
    freqList.Add("JFK:3");

    StringBuilder sb = new StringBuilder();

    foreach(string item in freqList)
    {
        sb.AppendFormat("{0} ", item);
    }

    //Trim last empty space from sb
    string sbStr = sb.ToString().TrimEnd(' ');

    //Create the string[] array
    string[] myArray = sb.ToString().Split(' '); //this creates an extra empty element

    Array.Sort(myArray, new MyListComparer());

    Appreciate your assistance.


    Marilyn Gambone

    Tuesday, June 25, 2013 4:08 PM
  • Since Array.Sort does not work with ArrayList, then use Sort which is a member of ArrayList: http://msdn.microsoft.com/en-us/library/0e743hdt.aspx.

    Consider the LINQ-based approach as well:

    var q = freqList.OfType<String>().OrderByDescending( s => int.Parse( s.Substring( s.LastIndexOf( ':' ) + 1 ) ) );

    Then call q.ToArray() or q.ToList() to obtain a typed array or list. By the way, modern generic collections like List<String> or List<MyItem> seems to be more suitable than collections of Objects.


    • Edited by Viorel_MVP Tuesday, June 25, 2013 6:37 PM ----
    • Marked as answer by deskcheck1 Tuesday, June 25, 2013 8:15 PM
    Tuesday, June 25, 2013 6:36 PM
  • Hi,

    This LINQ-based worked for me.  Thanks!!!


    Marilyn Gambone

    Tuesday, June 25, 2013 8:16 PM