0

I am trying to modify this code that already exists.The code was developed around 2008 and I am trying to fix the sort issue. I am also thinking of changing the code but wanted to fix the issue first.

ArrayList lineEmpNrs = new ArrayList();
taMibMsftEmpDetails employeeDetails; //taMibMsftEmpDetails is a custom class file

while (!HeaderFile.EndOfStream) //headerfile is employee information text file.
{
    headerRow = HeaderFile.ReadLine();
    headerFields = headerRow.Split(',');
    employeeDetails = BuildLine(headerFields[1],headerFields[2],headerFields[3]);
    lineEmpNrs.Add(employeeDetails);
}

 private taMibMsftEmpDetails BuildLine(string EmpId, string EmpName, String ExpnsDate)
 {
     taMibMsftEmpDetails empSlNr = new taMibMsftEmpDetails();
     empSlNr.EmployeeId  = EmpId;
     empSlNr.EmployeeName   = EmpName;
     empSlNr.ExpenseDate = ExpnsDate;
     return empSlNr;
 }

The Headerfile contains employee expense details. The empID is the key here and the headerFile can contain 'n' number of lines with same EmpID appearing in random order in the file.

I use lineEmpNrs to build some other information based on EmpID. So I want to have lineEmpNrs sorted based on EmpID. I tried the regular sort method but it didn't work.

Please suggest.

5
  • 1
    Have you thought about using a Generic List<T> instead..? Commented Jul 26, 2013 at 16:33
  • What .Net version you have? Can you use LINQ? Commented Jul 26, 2013 at 16:37
  • The site is currently on .NET 2.0 but the code is very old. I thought of changing the code but this was some fix that I wanted to do as is. But if other options are better then I will rewrite. Commented Jul 26, 2013 at 16:38
  • What is the exact type of HeaderFile? FileStream? StreamReader? Commented Jul 26, 2013 at 16:39
  • @JoelCoehoorn: it is StreamReader Commented Jul 26, 2013 at 16:42

6 Answers 6

3

First - thus it is .Net 2.0 you can use strongly-typed generic list of type List<taMibMsftEmpDetails> instead of ArrayList:

List<taMibMsftEmpDetails> lineEmpNrs = new List<taMibMsftEmpDetails>();
// rest is same

Second - you can use method List<T>.Sort with Comparison<T> delegate to sort employees by id:

lineEmpNrs.Sort(delegate(taMibMsftEmpDetails e1, taMibMsftEmpDetails e2) { 
                   return e1.EmployeeId.CompareTo(e2.EmployeeId); 
                });

Instead of anonymous method you can create usual named method for comparing employees:

lineEmpNrs.Sort(CompareEmployees);

Also consider to improve naming in your code. Consider to use employees collection instead of lineEmpNrs, EmployeeDetails class instead of taMibMsftEmpDetails.

Sign up to request clarification or add additional context in comments.

1 Comment

@lazyberezovsky-> I have tried your option and testing it now. Once I make lineEmpNrs as List, will I have option to find out how many times the same EmpID exists in the list. Basically I am looking to find out empA record count is 99 and empB record count is 50 and so on. I had used this with Arraylist but now I have to modify it as lineEmpNrs is list now. Thanks.
2

This code is .Net 2.0 safe:

public static string ReadLines(StreamReader input)
{
    string line;
    while ( (line = input.ReadLine()) != null)
       yield return line;
}

private taMibMsftEmpDetails BuildLine(string EmpId, string EmpName, String ExpnsDate)
{
    taMibMsftEmpDetails empSlNr = new taMibMsftEmpDetails();
    empSlNr.EmployeeId  = EmpId;
    empSlNr.EmployeeName   = EmpName;
    empSlNr.ExpenseDate = ExpnsDate;
    return empSlNr;
}

List<taMibMsftEmpDetails> lineEmpNrs = new List<taMibMsftEmpDetails>();
foreach (string line in ReadLines(HeaderFile))
{
    headerFields = line.Split(',');
    lineEmpNrs.Add(BuildLine(headerFields[1],headerFields[2],headerFields[3]));
}
lineEmpNrs.Sort(delegate(taMibMsftEmpDetails a, taMibMsftEmpDetails a) 
   { 
      return a.EmployeeId.CompareTo(a.EmployeeId); 
   });    

If you can get to at least .Net 3.5 (still uses .Net 2.0 runtime), it gets that much simpler:

public static string ReadLines(StreamReader input)
{
    string line;
    while ( (line = input.ReadLine()) != null)
       yield return line;
}

var lineEmpNrs = ReadLines(HeaderFile)
   .Select(l => l.Split(','))
   .Select(l => new taMibMsftEmpDetails() 
       {
          EmployeeId   = l[1],
          EmployeeName = l[2],
          ExpenseDate  = l[3]
       })
   .OrderBy(l=> l.EmployeeId)
   .ToList();

1 Comment

I am looking to find out record count based on employee. for example, empA record count is 99 and empB record count is 50 and so on. I had used this with Arraylist but want to know which option in LIST has this feature. Is GroupBy doable to acheive what I am looking for? Thanks.
2

As pointed out below, this won't work on ArrayList, but you could convert lineEmpNrs to a List<taMibMsftEmpDetails>.

LINQ is perfect here.

var sortedList = lineEmpNrs.OrderBy(emp => emp.EmployeeId);

After seeing your comment, this will only work if you can bump your code from .NET 2.0 to 3.5 or higher.

6 Comments

heh, saw the folly as soon as I hit the submit answer button. Thanks guys.
ArrayList doesn't I believe
emp is a variable you could name it anything you like look up lambda expressions when you get an opportunity
As @DJKRAZE mentions, yes, do some research into Lambda expressions. It's a placeholder variable that represents one item in the list of items that you are iterating through to order.
@GarrisonNeely: I don't get to see orderby when I type lineEmpNrs. What am I missing here?
|
1

You can use the ArrayList as a List

var enumerableCollection = from taMibMsftEmpDetails ln in lineEmpNrs
                                        orderby ln.EmployeeId
                                        select ln;

You can convert to Array or use the List

Comments

1

You can also load the data in to a DataTable and sort via a DataView.

    DataTable dt = new DataTable();
    dt.Columns.Add("EmpID");
    dt.Columns.Add("Field2");
    dt.Columns.Add("Field3");

    // Read file, split values, add to table
    while (!HeaderFile.EndOfStream) {

        headerRow  = HeaderFile.ReadLine();
        headerFields = headerRow.Split(',');

        // Create row and add it to the table
        DataRow dr = dt.NewRow();
        dr["EmpID"] = headerFields[0];
        dr["Field1"] = headerFields[1];
        dr["Field2"] = headerFields[2];
        dt.ImportRow(dr);
    }

    // Sort table by EmpID
    DataView dv = dt.DefaultView;
    dv.Sort = "EmpID ASC";
    dt = dv.ToTable();

Comments

1

The regular sort method should work alongside a custom compare method, something like the following:

private class sortByEmployeeIdHelper: IComparer
{
   int IComparer.Compare(object a, object b)
   {
       taMibMsftEmpDetails employeeA = (taMibMsftEmpDetails)a;
       taMibMsftEmpDetails employeeB = (taMibMsftEmpDetails)b;

       //employee id is numeric?
       int id = int.Parse(employeeA.EmployeeId);
       return id.CompareTo(int.Parse(employeeB.EmployeeId));
   }
}

IComparer myComparer = new sortByEmployeeIdHelper();
lineEmpNrs.Sort(myComparer);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.