2010-06-03 73 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做了诀窍。