改变C#排序行为

时间:2010-06-03 15:08:22

标签: c# linq sorting

假设我有字符串abc_abc2_。现在,通常在排序时,我会在abc2_之后进行C#abc_排序,留下结果:

  1. abc_
  2. abc2_
  3. 如果重要的话,我用这个来排序:

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

    我该如何改变?我希望abc_能够到最后。反转不是一个选项,因为列表包含两个以上的元素。

5 个答案:

答案 0 :(得分:4)

OrderBy方法可能会采用IComparer<T>参数。 (我不确定该重载是否可以与查询理解语法一起使用,或者它是否仅在使用fluent扩展方法语法时可用。)

由于目前尚不清楚您的排序算法究竟应该涉及什么,因此我将继续实施所需的IComparer<T>作为读者的练习。

答案 1 :(得分:4)

最简单的解决方案是使用.NET Framework内置的序数字符串比较器:

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

不需要自定义Comparer类!

答案 2 :(得分: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);

答案 3 :(得分:0)

我仍然不确定我们试图排序的实际模式,但我写了我认为可以解决的问题。我看到“_”是一种通配符,其中“abc2_”将是“abc_”的子集。但是从OP的评论“bar_”&lt; “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;
        }
    }

你可以看到我只是在找到“_”的位置加权一个字。如果这是在正确的轨道上,请告诉我。

答案 4 :(得分:0)

使用CompareOptions.Ordinal就可以了。