2015-01-14 18 views
0

我有一個「名稱」屬性包含名稱的類象"1_[AnnualRevenue]","2_[ResellerType]","3_xxx"....排序與數值類的字符串字段屬性

我的課就像

class xxx 
{ 
private string fileName; 
public string FileName 
     { 
      get { return fileName; } 
      set { fileName = value; } 
     } 
} 

而且我指定的值對象的類。像xxx.FileName="1_[AnnualRevenue]";

現在我有一個列表類。現在根據這個類屬性對列表進行排序。

現在我想根據數字順序對字段進行排序,我的意思是1到2秒等等。

然後將它寫入文件流。

任何機構都可以幫助我解決這個問題。 在此先感謝。

+2

你是說你有,你想他們的名稱屬性進行排序類的列表?如果您展示了該類的代碼示例以及如何存儲它的實例,那將會很有幫助。 –

+0

請展示您的課程以及價值的示例 –

+0

您是否在文件名稱開頭討論'N_'數字? –

回答

2

內部排序,但你想通過數字來排序,可能是最好的辦法是實行IComparable,然後將您的自定義排序代碼放在CompareTo方法中。然後,您不必在每次要對列表進行排序時編寫更復雜的Lambda語句,只需在列表中調用Sort()方法即可。

您也可以處理其中FileName屬性不包含下劃線或null,而不是在你的代碼OrderBy獲得異常(這是將與大多數其他的答案中發生什麼情況)。

我做了一些其他的變化也 - 覆蓋ToString方法,所以你可以很容易地顯示數值到控制檯窗口,並用自動屬性語法的FileName屬性,因此我們可以刪除支持字段:

class xxx : IComparable<xxx> 
{ 
    public string FileName { get; set; } 

    public int CompareTo(xxx other) 
    { 
     // Short circuit if any object is null, if the 
     // Filenames equal each other, or they're empty 
     if (other == null) return 1; 
     if (FileName == null) return (other.FileName == null) ? 0 : -1; 
     if (other.FileName == null) return 1; 
     if (FileName.Equals(other.FileName)) return 0; 
     if (string.IsNullOrWhiteSpace(FileName)) 
      return (string.IsNullOrWhiteSpace(other.FileName)) ? 0 : -1; 
     if (string.IsNullOrWhiteSpace(other.FileName)) return 1; 

     // Next, try to get the numeric portion of the string to compare 
     int thisIndex; 
     int otherIndex; 

     var thisSuccess = int.TryParse(FileName.Split('_')[0], out thisIndex); 
     var otherSuccess = int.TryParse(other.FileName.Split('_')[0], out otherIndex); 

     // If we couldn't get the numeric portion of the string, use int.MaxValue 
     if (!thisSuccess) 
     { 
      // If neither has a numeric portion, just use default string comparison 
      if (!otherSuccess) return FileName.CompareTo(other.FileName); 
      thisIndex = int.MaxValue; 
     } 
     if (!otherSuccess) otherIndex = int.MaxValue; 

     // Return the comparison of the numeric portion of the two filenames 
     return thisIndex.CompareTo(otherIndex); 
    } 

    public override string ToString() 
    { 
     return FileName; 
    } 
} 

現在,你可以叫Sort您的名單:

List<xxx> list = new List<xxx> 
{ 
    new xxx {FileName = "13_a"}, 
    new xxx {FileName = "8_a"}, 
    new xxx {FileName = null}, 
    new xxx {FileName = "1_a"}, 
    new xxx {FileName = "zinvalid"}, 
    new xxx {FileName = "2_a"}, 
    new xxx {FileName = ""}, 
    new xxx {FileName = "invalid"} 
}; 

list.Sort(); 

Console.WriteLine(string.Join("\n", list)); 

// Output (note the first two are the empty string and the null value): 
// 
// 
// 1_a 
// 2_a 
// 8_a 
// 13_a 
// invalid 
// zinvalid 
+0

順便說一下,不知道如何與FileNames,但是如果你在代碼的某個地方向它們添加數字,只需給你的類一個'int Rank {get; set;}'屬性並且除了FileName之外還可以設置它。如果你這樣做了,那麼你可以這樣做:'list.OrderBy(i => i.Rank)',你不必創建一個自定義的CompareTo方法。 –

2

您可以使用LINQ來爲你做的

List<xxx> orderedList = unOrderedList.OrderBy(o => Convert.ToInt32(o.FileName.Split('_').First())).ToList(); 

Editted代表意見的答案 - 他指出,我們的確需要轉換爲整數正確排序。

+0

它會在哪裏放10_a,20_a,解決方案與上面相同 –

+0

儘管我需要嘗試,但這聽起來不錯,純數字訂購 –

2

你可以像下面對列表進行排序:

List<xxx> list = new List<xxx> 
{ 
    new xxx { FileName = "3_a" }, 
    new xxx { FileName = "1_a" }, 
    new xxx { FileName = "2_a" }, 
    new xxx { FileName = "8_a" } 
}; 
var sorted = list.OrderBy(it => Convert.ToInt32(it.FileName.Split('_')[0]));//using System.Linq; 

,你可以寫在名單如下磁盤文件:

using (TextWriter tw = new StreamWriter("C:\\FileNames.txt")) 
      { 
       foreach (var item in sorted) 
       { 
        tw.WriteLine(item.FileName.ToString()); 
       } 
      } 
+1

它會在哪裏放10_a,20_a –

+0

不錯!可能不需要在FileName ...上調用'.ToString()':p –

0

這不應該是複雜的,這就是我更多信息:

  • 創建一個結構Dictionary<int,List<string>>

  • 從每個文件名中分離出數字並將其添加到詞典中,文件名將被添加到List<string>,我們使用List以防萬一有多個文件具有相同編號,因此它們都屬於同一個鍵。如果你能保證數字不會再複製就可以使用Dictionary<int,string>

  • 排序的字典基於整數鍵

僞代碼將是這樣的:

  • 對於字符串,使用分隔符「_」分割字符串,因此生成的字符串[]將在第0個索引處具有編號,該索引可以被轉換爲整數並用作關鍵字。事實上,你可以計劃使用下面的數據結構,這將由於屬性是String

SortedDictionary<int,List<string>>

+0

如果您在將其轉換爲工作代碼時遇到問題,請告知我。 –