Home

Sorting a List

     

Introduction

Sorting a list consists of re-arranging its members in a certain order. The arrangement depends on the type of values of the list. That is, the list can be arranged in ascending order, in chronological order, in incremental order, or in logical order.

   

Practical Learning: Introducing Operations

  1. Start Microsoft Visual Studio
  2. Create a Windows Forms Application named AltairRealtors2
  3. To save the project, on the Standard toolbar, click the Save All button
  4. Accept the options and click Save
  5. To create a new class, in the Class View, right-click AltairRealtors1 -> Add -> Class...
  6. Change the name to Property and press Enter
  7. Complete the class as follows:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace AltairRealtors1
    {
        public enum PropertyType
        {
            Condominium,
            Townhouse,
            SingleFamily,
            Unknown
        }
    
        public enum PropertyCondition
        {
            Unknown,
            Excellent,
            Good,
            NeedsRepair,
            BadShape
        }
    
        [Serializable]
        public class Property
        {
            private int nbr;
            private PropertyType tp;
            private string ct;
            private string stt;
            private PropertyCondition cond;
            private short beds;
            private float baths;
            private int levels;
            private int yr;
            private decimal val;
    
            public Property()
            {
                nbr = 0;
                tp = PropertyType.Unknown;
                ct = "Unknown";
                stt = "AA";
                cond = PropertyCondition.Unknown;
                beds = 0;
                baths = 0.00F;
                levels = 0;
                yr = 1900;
                val = 0M;
            }
    
            public Property(int propNbr, PropertyType type, string city,
                            string state, PropertyCondition condition,
                            short bedrooms, float bathrooms, int stories,
                            int year, decimal value)
            {
                nbr = propNbr;
                tp = type;
                ct = city;
                stt = state;
                cond = condition;
                beds = bedrooms;
                baths = bathrooms;
                levels = stories;
                yr = year;
                val = value;
            }
    
            public int PropertyNumber
            {
                get { return nbr; }
                set { nbr = value; }
            }
    
            public PropertyType Type
            {
                get { return tp; }
                set { tp = value; }
            }
    
            public string City
            {
                get { return ct; }
                set { ct = value; }
            }
    
            public string State
            {
                get { return stt; }
                set { stt = value; }
            }
    
            public PropertyCondition Condition
            {
                get { return cond; }
                set { cond = value; }
            }
    
            public short Bedrooms
            {
                get
                {
                    if (beds <= 1)
                        return 1;
                    else
                        return beds;
                }
                set { beds = value; }
            }
    
            public float Bathrooms
            {
                get { return (baths <= 0) ? 0.00f : baths; }
                set { baths = value; }
            }
    
            public int Stories
            {
                get { return levels; }
                set { levels = value; }
            }
    
            public int YearBuilt
            {
                get { return yr; }
                set { yr = value; }
            }
    
            public decimal MarketValue
            {
                get { return (val <= 0) ? 0.00M : val; }
                set { val = value; }
            }
        }
    }
  8. In the Solution Explorer, right-click Form1.cs and click Rename
  9. Type AltairRealtors.cs and press Enter twice to display the form
  10. Design the form as follows:
     
    Altair Realtors
     
    Control Text Name Other Properties
    ListView List View   lvwProperties Anchor: Top, Bottom, Left, Right
    Columns  
    (Name) Text TextAlign Width
    colIndex #   40
    colPropertyNumber Prop #   55
    colDateListed Date Listed Center  
    colPropertyType Prop Type   85
    colCity City    
    colState State    
    colCondition Condition    
    colBedrooms Beds Right 65
    colBathrooms Baths Right 65
    colStories Stories Right 75
    colYearBuilt Year Right 70
    colMarketValue Value Right  
    Button Button Close btnClose Anchor: Bottom, Right
  11. Double-click an unoccupied area of the form and implement the Load event as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace AltairRealtors2
    {
        public partial class AltairRealtors : Form
        {
            List<Property> lstProperties;
    
            public AltairRealtors()
            {
                InitializeComponent();
            }
    
            private void AltairRealtors_Load(object sender, EventArgs e)
            {
                lstProperties = new List<Property>();
    
                lstProperties.Add(new Property(524880, PropertyType.SingleFamily, "Silver Spring", "MD",
                                  PropertyCondition.Good, 4, 2.50f, 3, 1995, 495880.00M));
                lstProperties.Add(new Property(688364, PropertyType.SingleFamily, "Alexandria", "VA",
                            PropertyCondition.Excellent, 4, 3.5f, 2, 2000, 620724.00M));
                lstProperties.Add(new Property(611464, PropertyType.SingleFamily, "Laurel", "MD",
                            PropertyCondition.Good, 0, 0F, 2, 0, 422625.00M));
                lstProperties.Add(new Property(749562, PropertyType.Townhouse, "Gettysburg", "WV",
                            PropertyCondition.Good, 3, 2.5F, 3, 2002, 425400.00M));
                lstProperties.Add(new Property(420115, PropertyType.Unknown, "Washington", "DC",
                            PropertyCondition.Unknown, 2, 0F, 0, 1982, 312555.00M));
                lstProperties.Add(new Property(200417, PropertyType.Condominium, "Germantown", "MD",
                            PropertyCondition.Excellent, 2, 1f, 0, 0, 215495.00M));
                lstProperties.Add(new Property(927474, PropertyType.Townhouse, "Arlington", "VA",
                            PropertyCondition.BadShape, 4, 2.5f, 3, 1992, 415665.00M));
                lstProperties.Add(new Property(682630, PropertyType.SingleFamily, "Martinsburg", "WV",
                            PropertyCondition.Good, 4, 3.5f, 3, 2005, 325000.00M));
                lstProperties.Add(new Property(288540, PropertyType.Condominium, "Silver Spring", "MD",
                            PropertyCondition.Good, 1, 1f, 0, 2000, 242775.00M));
                lstProperties.Add(new Property(247472, PropertyType.SingleFamily, "Silver Spring", "MD",
                            PropertyCondition.Excellent, 3, 3f, 3, 1996, 625450.00M));
                lstProperties.Add(new Property(297446, PropertyType.Townhouse, "Laurel", "MD",
                            PropertyCondition.Unknown, 4, 1.5F, 2, 2002, 412885.00M));
                lstProperties.Add(new Property(924792, PropertyType.SingleFamily, "Washington", "DC",
                            PropertyCondition.Good, 5, 3.5F, 3, 2000, 555885.00M));
                lstProperties.Add(new Property(294796, PropertyType.SingleFamily, "Falls Church", "VA",
                            PropertyCondition.Excellent, 5, 2.5f, 2, 1995, 485995.00M));
                lstProperties.Add(new Property(811155, PropertyType.Condominium, "Alexandria", "VA",
                            PropertyCondition.Good, 1, 1.0F, 0, 2000, 352775.00M));
                lstProperties.Add(new Property(447597, PropertyType.Townhouse, "Hyattsville", "MD",
                            PropertyCondition.Excellent, 3, 2f, 3, 1992, 365880.00M));
                lstProperties.Add(new Property(297415, PropertyType.Townhouse, "ashington", "DC",
                            PropertyCondition.Good, 4, 3.5f, 1, 2004, 735475.00M));
                lstProperties.Add(new Property(475974, PropertyType.SingleFamily, "Gaithersburg", "MD",
                            PropertyCondition.Unknown, 4, 2.5f, 1, 1965, 615775.00M));
                lstProperties.Add(new Property(927409, PropertyType.Condominium, "McLean", "VA",
                            PropertyCondition.Excellent, 1, 1f, 12, 2006, 485900.00M));
                lstProperties.Add(new Property(304750, PropertyType.Condominium, "Washington", "DC",
                            PropertyCondition.Unknown, 2, 2f, 6, 1992, 388665.00M));
                lstProperties.Add(new Property(207850, PropertyType.Townhouse, "Rockville", "MD",
                            PropertyCondition.Good, 3, 2.5F, 2, 1988, 525995.00M));
    
                FileStream stmProperties = null;
                BinaryFormatter bfmProperties = new BinaryFormatter();
    
                // If this directory doesn't exist, create it
                Directory.CreateDirectory(@"C:\Altair Realtors");
                // This is the file that holds the list of properties
                string Filename = @"C:\Altair Realtors\Properties.atr";
    
                // Find out if there is already a file (from the previous lesson).
                // If that file exists, delete it
                if (File.Exists(Filename))
                    File.Delete(Filename);
    
                try
                {
                    // Save the list of properties
                    stmProperties = new FileStream(Filename,
                                                   FileMode.Create,
                                                   FileAccess.Write,
                                                   FileShare.Write);
                    bfmProperties.Serialize(stmProperties, lstProperties);
                }
                finally
                {
                    stmProperties.Close();
                }
            }
        }
    }
  12. Return to the form and double-click the Close button
  13. Change the file as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace AltairRealtors2
    {
        public partial class AltairRealtors : Form
        {
            List<Property> lstProperties;
    
            public AltairRealtors()
            {
                InitializeComponent();
            }
    
            private void AltairRealtors_Load(object sender, EventArgs e)
            {
                FileStream stmProperties = null;
                BinaryFormatter bfmProperties = new BinaryFormatter();
    
                // This is the file that holds the list of properties
                string Filename = @"C:\Altair Realtors\Properties.atr";
    
                // Find out if there is already a file that contains a list of properties.
                // If that file exists, open it.
                if (File.Exists(Filename))
                {
                    stmProperties = new FileStream(Filename,
                                                  FileMode.Open,
                                                  FileAccess.Read,
                                                  FileShare.Read);
    
                    try
                    {
                        // Retrieve the list of items from file
                        lstProperties = (List<Property>)bfmProperties.Deserialize(stmProperties);
    
                        var properties = from props
                                         in lstProperties
                                         select props;
    
                        int i = 0;
    
                        foreach (var prop in properties)
                        {
                            ListViewItem lviProperty = new ListViewItem((i + 1).ToString());
    
                            lviProperty.SubItems.Add(prop.PropertyNumber.ToString());
                            lviProperty.SubItems.Add(prop.Type.ToString());
                            lviProperty.SubItems.Add(prop.City);
                            lviProperty.SubItems.Add(prop.State);
                            lviProperty.SubItems.Add(prop.Condition.ToString());
                            lviProperty.SubItems.Add(prop.Bedrooms.ToString());
                            lviProperty.SubItems.Add(prop.Bathrooms.ToString("F"));
                            lviProperty.SubItems.Add(prop.Stories.ToString());
                            lviProperty.SubItems.Add(prop.YearBuilt.ToString());
                            lviProperty.SubItems.Add(prop.MarketValue.ToString("F"));
                            lvwProperties.Items.Add(lviProperty);
    
                            i++;
                        }
                    }
                    finally
                    {
                        stmProperties.Close();
                    }
                }
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  14. Return to the form and change the Load event as follows:
  15. Execute the application to see the result
     
    Altair Realtors
  16. Close the form and return to your programming environment
  17. Display the form

Ascending Order

When you create a list, you add the items in any order of your choice. When you create a select statement, the items are added to its list in the order they appear in the main list. When treating the new list or when presenting it to the user, you may want to arrange it in alphabetical, numerical, or chronological order.

To support this operation, the LINQ provides the orderdy operator. To apply it, write the operator before the select operation followed by the from list. Here is an example:

private void Exercise_Load(object sender, EventArgs e)
{
    var numbers = new List<int>();

    numbers.Add(12);
    numbers.Add(45);
    numbers.Add(38);
    numbers.Add(5);
    numbers.Add(128);
    numbers.Add(525);
    numbers.Add(2448);
    numbers.Add(39);
    numbers.Add(632);
    numbers.Add(207);

    var number = from n
                 in numbers
                 orderby n
                 select n;

    foreach (var member in number)
        lbxNumbers.Items.Add(member.ToString());
}

This would produce:

Numbers

If you apply the orderby operator simply followed by a variable, the list is ordered alphabetically or numerically depending on the types of values in the list. This is referred to as ascending. To re-enforce this, you can follow the variable with the ascending keyword. Here is an example:

private void Exercise_Load(object sender, EventArgs e)
{
    var numbers = new List<int>();

    numbers.Add(12);
    numbers.Add(45);
    numbers.Add(38);
    numbers.Add(5);
    numbers.Add(128);
    numbers.Add(525);
    numbers.Add(2448);
    numbers.Add(39);
    numbers.Add(632);
    numbers.Add(207);

    var number = from n
                 in numbers
                 orderby n ascending
                 select n;

    foreach (var member in number)
        lbxNumbers.Items.Add(member.ToString());
}

Descending Order

You can arrange a list in reverse ascending order, in decremental order, or in reverse chronological order. To support this, the LINQ uses the orderby keyword in combination with the descending keyword. Here is an example:

private void Exercise_Load(object sender, EventArgs e)
{
    var numbers = new List<int>();

    numbers.Add(12);
    numbers.Add(45);
    numbers.Add(38);
    numbers.Add(5);
    numbers.Add(128);
    numbers.Add(525);
    numbers.Add(2448);
    numbers.Add(39);
    numbers.Add(632);
    numbers.Add(207);

    var number = from n
                 in numbers
                 orderby n descending
                 select n;

    foreach (var member in number)
        lbxNumbers.Items.Add(member.ToString());
}

This would produce:

Numbers

Sorting With Class

Sorting the members of a primitive-based list is quite easy. This is because the classes (structures) of each data type implement the IComparable interface. This also makes it easy to sort the values of a select statment. This means that, to arrange the list of values, in the orderby statement, type the name of the from variable and use the period operator to specify the base of what member you want to arrange the list. Here is an example:

using System;
using System.Linq;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;

public class Exercise : Form
{
    Button btnShow;

    private ColumnHeader colEmployeeNumber;
    private ColumnHeader colFirstName;
    private ColumnHeader colLastName;
    private ColumnHeader colHourlySalary;

    ListView lvwEmployees;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        btnShow = new Button();
        btnShow.Location = new System.Drawing.Point(12, 8);
        btnShow.Width = 75;
        btnShow.Text = "Show";
        btnShow.Click += new System.EventHandler(this.btnShowClick);

        lvwEmployees = new ListView();
        lvwEmployees.Anchor = AnchorStyles.Left | AnchorStyles.Top |
                              AnchorStyles.Right | AnchorStyles.Bottom;
        lvwEmployees.FullRowSelect = true;
        lvwEmployees.GridLines = true;
        lvwEmployees.Location = new Point(12, 40);
        lvwEmployees.Size = new System.Drawing.Size(270, 100);
        lvwEmployees.View = View.Details;

        colEmployeeNumber = new ColumnHeader();
        colEmployeeNumber.Text = "Empl #";
        colEmployeeNumber.Width = 50;
        lvwEmployees.Columns.Add(colEmployeeNumber);

        colFirstName = new ColumnHeader();
        colFirstName.Text = "First Name";
        colFirstName.Width = 80;
        lvwEmployees.Columns.Add(colFirstName);

        colLastName = new ColumnHeader();
        colLastName.Text = "Last Name";
        colLastName.Width = 80;
        colLastName.TextAlign = HorizontalAlignment.Center;
        lvwEmployees.Columns.Add(colLastName);

        colHourlySalary = new ColumnHeader();
        colHourlySalary.Text = "Salary";
        colHourlySalary.Width = 50;
        colHourlySalary.TextAlign = HorizontalAlignment.Right;
        lvwEmployees.Columns.Add(colHourlySalary);

        Size = new System.Drawing.Size(300, 180);
        Controls.Add(btnShow);
        Controls.Add(lvwEmployees);
        Text = "Employees";
    }

    private void btnShowClick(object sender, EventArgs e)
    {
        var employees = new Employee[]
        {
            new Employee(971974, "Patricia", "Katts", 24.68M),
            new Employee(208411, "Raymond", "Kouma", 20.15M),
            new Employee(279374, "Hél�ne", "Mukoko", 15.55M),
            new Employee(707912, "Bertrand", "Yamaguchi", 24.68M),
            new Employee(971394, "Gertrude", "Monay", 20.55M)
        };

        var empls = from staffMembers
                    in employees
                    orderby staffMembers.EmployeeNumber
                    select staffMembers;

        foreach (var staff in empls)
        {
            ListViewItem lviCollection =
            	new ListViewItem(staff.EmployeeNumber.ToString());

            lviCollection.SubItems.Add(staff.FirstName);
            lviCollection.SubItems.Add(staff.LastName);
            lviCollection.SubItems.Add(staff.HourlySalary.ToString());
            lvwEmployees.Items.Add(lviCollection);
        }
    }

    [STAThread]
    public static int Main()
    {
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

public class Employee
{
    public int EmployeeNumber;
    public string FirstName;
    public string LastName;
    public decimal HourlySalary;

    public Employee(int number = 0,
                       string firstName = "John",
                       string lastName = "Doe",
                       decimal salary = 0M)
    {
        EmployeeNumber = number;
        FirstName = firstName;
        LastName = lastName;
        HourlySalary = salary;
    }

    internal string GetFullName()
    {
        return LastName + ", " + FirstName;
    }
}

This would produce:

Employees

In the same way, you can specify by what member of the class the list should be sorted.

Practical Learning: Sorting Records

  1. On the form, click the list view and, in the Properties window, click the Events button
  2. In the Events section of the Properties window, double-click ColumnClick and implement the event as follows:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace AltairRealtors2
    {
        public partial class AltairRealtors : Form
        {
            List lstProperties;
    
            bool column0SortedAscending;
            bool column1SortedAscending;
            bool column2SortedAscending;
            bool column3SortedAscending;
            bool column4SortedAscending;
            bool column5SortedAscending;
            bool column6SortedAscending;
            bool column7SortedAscending;
            bool column8SortedAscending;
            bool column9SortedAscending;
    
            public AltairRealtors()
            {
                InitializeComponent();
            }
    
            . . . No Change       
    
            private void lvwProperties_ColumnClick(object sender, ColumnClickEventArgs e)
            {
                int i = 1;
                lvwProperties.Items.Clear();
                IEnumerable properties = null;
    
                if (e.Column == 0)
                {
                    properties = from props
                                 in lstProperties
                                 select props;
                }
                else
                {
                    if (e.Column == 1)
                    {
                        if (column0SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.PropertyNumber ascending
                                         select Props;
                            column0SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.PropertyNumber descending
                                         select Props;
                            column0SortedAscending = false;
                        }
                    }
                    else if (e.Column == 2)
                    {
                        if (column1SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Type ascending
                                         select Props;
                            column1SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Type descending
                                         select Props;
                            column1SortedAscending = false;
                        }
                    }
                    else if (e.Column == 3)
                    {
                        if (column2SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.City ascending
                                         select Props;
                            column2SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.City descending
                                         select Props;
                            column2SortedAscending = false;
                        }
                    }
                    else if (e.Column == 4)
                    {
                        if (column3SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.State ascending
                                         select Props;
                            column3SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.State descending
                                         select Props;
                            column3SortedAscending = false;
                        }
                    }
                    else if (e.Column == 5)
                    {
                        if (column4SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Condition ascending
                                         select Props;
                            column4SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Condition descending
                                         select Props;
                            column4SortedAscending = false;
                        }
                    }
                    else if (e.Column == 6)
                    {
                        if (column5SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Bedrooms ascending
                                         select Props;
                            column5SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Bedrooms descending
                                         select Props;
                            column5SortedAscending = false;
                        }
                    }
                    else if (e.Column == 7)
                    {
                        if (column6SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Bathrooms ascending
                                         select Props;
                            column6SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Bathrooms descending
                                         select Props;
                            column6SortedAscending = false;
                        }
                    }
                    else if (e.Column == 8)
                    {
                        if (column7SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Stories ascending
                                         select Props;
                            column7SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.Stories descending
                                         select Props;
                            column7SortedAscending = false;
                        }
                    }
                    else if (e.Column == 9)
                    {
                        if (column8SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.YearBuilt ascending
                                         select Props;
                            column8SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.YearBuilt descending
                                         select Props;
                            column8SortedAscending = false;
                        }
                    }
                    else if (e.Column == 10)
                    {
                        if (column9SortedAscending == false)
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.MarketValue ascending
                                         select Props;
                            column9SortedAscending = true;
                        }
                        else
                        {
                            properties = from Props
                                         in lstProperties
                                         orderby Props.MarketValue descending
                                         select Props;
                            column9SortedAscending = false;
                        }
                    }
                }
    
                foreach (var prop in properties)
                {
                    ListViewItem lviProperty = new ListViewItem(i.ToString());
    
                    lviProperty.SubItems.Add(prop.PropertyNumber.ToString());
                    lviProperty.SubItems.Add(prop.Type.ToString());
                    lviProperty.SubItems.Add(prop.City);
                    lviProperty.SubItems.Add(prop.State);
                    lviProperty.SubItems.Add(prop.Condition.ToString());
                    lviProperty.SubItems.Add(prop.Bedrooms.ToString());
                    lviProperty.SubItems.Add(prop.Bathrooms.ToString("F"));
                    lviProperty.SubItems.Add(prop.Stories.ToString());
                    lviProperty.SubItems.Add(prop.YearBuilt.ToString());
                    lviProperty.SubItems.Add(prop.MarketValue.ToString("F"));
    
                    lvwProperties.Items.Add(lviProperty);
                    i++;
                }
            }
        }
    }
  3. Execute the application
  4. Close the form and return to your programming environment
 

Previous Copyright © 2010-2016, FunctionX Next