The problem statement is as below:
You have a list of runners and their race times and ages. Create a program to display the runners sorted by finish time with a column showing their finish position (ranking) within their age group.
The age groups are
0 - 18 years
18 - 40 years
40+ years
Read the following data from a column delimited (fixed field width) text file....
Name Time Age
--------------------
Jay 12 33
Hem 34 28
Umesh 22 37
Rahul 21 30
Clarke 13 33
Vinay 17 28
Mathew 10 28
Jen 9 29
Brad 15 14
After reading the problem, there are two ways to solve it just make use of variables or array of strings to store the data and achieve the result. Or the alternative way is to think in terms of objects.
So lets see how the alternative approach looks like, as you have a list of running at hand, you can think of creating a class which represents each Participant. As the participants have various parameters to be considered, you can have these parameters as properties of the Participant class.
Hence you can create a Participant class with the following public properties,
Name, Time, Age and Ranking.
Create a class library called Business entity and add the following Participant class into that class library, so that you have separation of business enity/objects from the presentation layer.
Code for the class:
public class ParticipantDetails
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
private int _time;
public int Time
{
get { return _time; }
set { _time = value; }
}
private int _ranking;
public int Ranking
{
get { return _ranking; }
set { _ranking = value; }
}
}
Once the class is ready, you can now think of dividing the task involved into smaller modules or methods say for example, based on the above problem, I can divide it into the following steps
- Read each line of data from the file.
- Process each line of data to get the Participant object.
- Get a list of participants based on the age group mentioned.
- Assign ranks with the group
For each of the steps above the following is the method implementation.
Code for each step mentioned above:
- Read each line of data from the file.
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader("c:\\test.txt");
while ((line = file.ReadLine()) != null)
{ if (Linecount > 1)
{
Participant = GetParticipantDetails(line);
Participants.Add(Participant);
} Linecount++;
}
Process each line of data to get the Participant object.
private ParticipantDetails GetParticipantDetails(string line)
{
ParticipantDetails PDetails = new ParticipantDetails();
line = line.Trim();
//To get the name
int delimiterIndex = line.IndexOf(" ");
PDetails.Name = line.Substring(0, delimiterIndex);
line = line.Replace(PDetails.Name, "");
line = line.Trim();
//to get the age
delimiterIndex = line.IndexOf(" ");
PDetails.Age = int.Parse(line.Substring(0, delimiterIndex));
line = line.Replace(PDetails.Age.ToString(), "");
line = line.Trim();
//to get the time
delimiterIndex = line.IndexOf(" ");
PDetails.Time = int.Parse(line.Substring(0, line.Length));
line = line.Replace(PDetails.Time.ToString(), "");
line = line.Trim();
return PDetails;
}
- Get a list of participants based on the age group mentioned.
private List<ParticipantDetails> GetGroupBasedOnAgeLimits(int StartAge, int EndAge, List<ParticipantDetails> lstParticipants) { List<ParticipantDetails> Group = new List<ParticipantDetails>(); foreach (ParticipantDetails P in lstParticipants) { if (P.Age >= StartAge && P.Age <= EndAge) Group.Add(P); } return Group; }
Assign ranks with the group
private void AssignRanks(ref ParticipantDetails[] PDetails)
{
int Rank = 1;
foreach (ParticipantDetails P in PDetails)
{
P.Ranking = Rank;
Rank++;
}
}
Once you have all the methods, you can move these methods into a helper class for better code separation from the presentation layer.
In order to sort the participants with in a age group based on the time, you can implement a custom sorting for the Paticipant class, by implementing the IComparable interface in the Participant class.
Implementation of the custom sorting is as shown below:
public class ParticipantDetails:IComparable
public int CompareTo(object x)
{
ParticipantDetails Participant = (ParticipantDetails)x;
return this.Time.CompareTo(Participant.Time);
}
In the code, I have made use of the list of Participants instead of Array of Participant class or ArrayList which is more generic.
Hope this article would make you think to take the alternative approach of objects and goal towards achieving a much cleaner and organized code for each problem you come across during coding..
I have attached the working example of the above problem for further reference.