|
Sorting a List |
|
|
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
|
|
- Start Microsoft Visual Studio
- Create a Windows Forms Application
named AltairRealtors2
- To save the project, on the Standard toolbar, click the Save All
button
- Accept the options and click Save
- To create a new class, in the Class View, right-click
AltairRealtors1 -> Add -> Class...
- Change the name to Property and press Enter
- 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; }
}
}
}
- In the Solution Explorer, right-click Form1.cs and click Rename
- Type AltairRealtors.cs and press Enter twice to display the
form
- Design the form as follows:
|
Control |
Text |
Name |
Other Properties |
ListView |
|
|
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 |
|
Close |
btnClose |
Anchor: Bottom, Right |
|
- 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();
}
}
}
}
- Return to the form and double-click the Close button
- 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();
}
}
}
- Return to the form and change the Load event as follows:
- Execute the application to see the result
- Close the form and return to your programming environment
- Display the form
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:
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());
}
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:
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:
In the same way, you can specify by what member of the
class the list should be sorted.
Practical
Learning: Sorting Records
|
|
- On the form, click the list view and, in the Properties window,
click the Events button
- 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++;
}
}
}
}
- Execute the application
- Close the form and return to your programming environment
|
|