2013-07-26 93 views
0

我想修改這個已經存在的代碼。代碼是在2008年左右開發的,我試圖解決排序問題。我也在考慮更改代碼,但首先要解決這個問題。在c中的數組列表排序#

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; 
} 

Headerfile包含員工費用明細。 empID是這裏的關鍵,headerFile可以包含'n'個具有相同EmpID的行,並以隨機順序出現在文件中。

我使用lineEmpNrs來構建一些基於EmpID的其他信息。所以我想要根據EmpID對lineEmpNrs進行排序。我嘗試了常規排序方法,但沒有奏效。

請建議。

+1

你有沒有想過使用'Generic List '而不是..? – MethodMan

+0

你有什麼.Net版本?你可以使用LINQ嗎? –

+0

該網站目前在.NET 2.0上,但代碼很舊。我想改變代碼,但這是我想要做的一些修復。但如果其他選項更好,我會重寫。 – Anirudh

回答

2

此代碼是NET 2.0安全:

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); 
    });  

如果你能得到至少NET 3.5的(仍然使用的.Net 2.0運行時),它會簡單得多:

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(); 
+0

我正在尋找基於員工的記錄數。例如,empA記錄數爲99,empB記錄數爲50,依此類推。我曾將這與Arraylist一起使用,但想知道LIST中的哪個選項具有此功能。 GroupBy是否可以實現我所尋找的目標?謝謝。 – Anirudh

2

正如以下指出的那樣,這對ArrayList不起作用,但是您可以將lineEmpNrs轉換爲List<taMibMsftEmpDetails>

LINQ在這裏是完美的。

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

看到您的評論後,只有當您可以將代碼從.NET 2.0升級到3.5或更高版本時,纔會有效。

+0

列表不通用 –

+0

這是行不通的,因爲它是一個ArrayList – Alden

+0

嘿,一旦看到愚蠢,因爲我打提交接聽按鈕。多謝你們。 –

1

您可以使用ArrayList中作爲List

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

您可以轉換到Array或使用List

3

首先 - 因此它的.Net 2.0,你可以使用類的強類型的泛型列表List<taMibMsftEmpDetails>,而不是ArrayList

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

二 - 您可以使用方法List<T>.SortComparison<T>委託給由ID員工進行排序:

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

而不是匿名方法可以用於比較員工創造通常命名的方法:

lineEmpNrs.Sort(CompareEmployees); 

也可以考慮提高你的代碼命名。考慮使用employees集合而不是lineEmpNrs,EmployeeDetails類而不是taMibMsftEmpDetails

+0

@ lazyberezovsky->我已經嘗試過你的選擇,現在就進行測試。一旦我將lineEmpNrs設置爲List,我是否可以選擇查找列表中存在相同EmpID的次數。基本上我正在尋找empA記錄數是99並且empB記錄數是50等等。我曾經使用過Arraylist,但現在我必須修改它,因爲lineEmpNrs現在列表。謝謝。 – Anirudh

1

您也可以將數據加載到DataTable中並通過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(); 
1

常規排序方法應該與一個自定義的工作比較法,類似如下:

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);