2010-06-03 218 views
4

可以說我有字符串abc_abc2_。現在,通常排序時我C#abc2_會來abc_後,留下的結果:更改C#排序行爲

  1. abc_
  2. abc2_

我用這來排序,如果它的問題:

 var element = from c in elements 
    orderby c.elementName ascending 
    select c; 

我該如何改變這種情況?我想abc_最後。反轉不是一種選擇,因爲列表包含兩個以上的元素。

+1

即使您有超過2個元素,對已排序的集合進行反轉也會爲您提供顛倒的順序。 – Simon 2010-06-03 15:09:50

+3

你只是想讓abc_最後一切按正常排序嗎?如果不是,你在尋找什麼樣的模式? – Eric 2010-06-03 15:10:05

+0

@Simon:如果我有1.aaa 2.abc_ 3.abc2_我不會在Reverse() – Erik 2010-06-03 15:11:43

回答

4

最簡單的解決方案是使用內置於.NET Framework中的順序串比較器:

var element = from c in elements 
    .OrderBy(c => c.elementName, StringComparer.Ordinal) 
    select c; 

沒有自定義比較類需要!

4

OrderBy方法可能會採取IComparer<T>參數。 (我不確定該超載是否可以與查詢理解語法一起使用,或者僅當使用流利的擴展方法語法時纔可用)。

由於不清楚你的排序算法應該涉及到什麼,所以我會請執行所需的IComparer<T>作爲讀者的練習。

+0

更好地嘗試使用內置的StringComparer類,請參閱我的答案。 – luksan 2010-06-05 16:34:19

1

如果你想強調不參與比較,我們可以做到這一點。所以:

class CustomComparer : Comparer<string> 
    {    
     public override int Compare(string a, string b) 
     { 
      //Jamiec fixed the line below.    
      return a.Replace("_", "").CompareTo(b.Replace("_", "")); 
     } 
    } 


var customComparer = new CustomComparer();          
var element = elements.OrderBy(c => c.elementName, customComparer); 
+0

我認爲答案非常接近。如果不是,OP可能只需編寫正確的單元測試並根據需要修改實現。 – Greg 2010-06-03 15:49:55

+0

這不會工作。 a.Replace(..)不會更改,它會返回一個新的字符串。所以它需要a.Replace(...)。CompareTo(b.Replace(...)) – Jamiec 2010-06-03 15:51:40

+0

@Jamiec - 我同意 – 2010-06-03 15:53:21

0

我仍然不確定實際的模式,我們試圖排序,但我寫了我認爲會是一個解決方案。我將「_」看作一種通配符,其中「abc2_」將是「abc_」的子集。但從OP的評論「bar_」<「barxyz」打破了我的理解。這是我的代碼,當我獲得更多的清晰度時,我可以修改它。

static void Main(string[] args) 
    { 
     List<Element> Elements = new List<Element>(); 
     Elements.Add(new Element("abc_")); 
     Elements.Add(new Element("abc2_")); 
     Elements.Add(new Element("aaa")); 

     var max = Elements.Max(e => e.Name.Length); 
     var result = Elements.OrderBy(e => e.Name, new CustomComparer(max)); 

     foreach (var item in result) 
      Console.WriteLine(item.Name); 

     Console.Read(); 

    } 

    class Element 
    { 
     public string Name { get; private set; } 
     public Element(string name) 
     { 
      this.Name = name; 
     } 
    } 

    class CustomComparer : Comparer<string> 
    { 
     private const string cWildCard = "_"; 
     private const char cHeavyChar = 'Z'; 
     public int Max { get; private set; } 
     public CustomComparer(int max) 
     { 
      this.Max = max; 
     } 
     public override int Compare(string a, string b) 
     { 
      string comp1 = string.Empty, comp2 = string.Empty; 

      int index = a.IndexOf(cWildCard); 
      if (index > 0) 
       comp1 = a.Substring(0, index).PadRight(this.Max, cHeavyChar); 
      index = b.IndexOf(cWildCard); 
      if (index > 0) 
       comp2 = b.Substring(0, index).PadRight(this.Max, cHeavyChar); 

      int result = comp1.CompareTo(comp2); 
      return result; 
     } 
    } 

你可以看到我只是從發現「_」的地方加重一個詞。讓我知道這是否正確。

0

使用CompareOptions.Ordinal做了訣竅。