c# – 实现自定义IComparer <>(带示例)

我刚刚编写了以下代码,它将通过其原生string.Compare()来排序字符串,但允许一组异常(在本例中为customPriority),它将优先于默认的string.Compare()函数.

这一切看起来有点长,我想知道是否有内置于.NET的内容允许这样做?

    var unorderered = new[] { "a", "b", "c", "x", "y", "z" };
    var ordered = unorderered.OrderBy(a => a, new CustomStringComparer());
    //expected order y,x,a,b,c,z

class CustomStringComparer : IComparer<string>
{
    int IComparer<string>.Compare(string x, string y)
    {
        if (x == y)
            return 0;
        else
        {
            //----------------------------
            //beginning of custom ordering
            var customPriority = new[] { "y", "x" };
            if (customPriority.Any(a => a == x) && customPriority.Any(a => a == y)) //both in custom ordered array
            {
                if (Array.IndexOf(customPriority, x) < Array.IndexOf(customPriority, y))
                    return -1;                   
                return 1;
            }
            else if (customPriority.Any(a => a == x)) //only one item in custom ordered array (and its x)                    
                return -1;
            else if (customPriority.Any(a => a == y)) //only one item in custom ordered array (and its y)                    
                return 1;
            //---------------------------
            //degrade to default ordering
            else
                return string.Compare(x, y);

        }
    }
}

解决方法:

首先,我认为重述问题是有用的:您希望按以下方式排序:

>给定数组中的索引;如果项目不在数组中,则索引为无穷大
>字符串本身

这意味着您可以通过对第一个条件使用OrderBy(),然后对第二个条件使用ThenBy()来实现排序顺序:

private static uint NegativeToMaxValue(int i)
{
    if (i < 0)
        return uint.MaxValue;
    return (uint)i;
}

…

var ordered = unorderered
    .OrderBy(a => NegativeToMaxValue(Array.IndexOf(new[] { "y", "x" }, a)))
    .ThenBy(a => a);

NegativeToMaxValue()是必要的,因为不在数组中的项应该是最后的,但它们通常是第一个,因为索引是-1. (执行相同操作的一种hackish和不可读的方法是直接将IndexOf()的结果转换为uint.)

如果你想通过创建IComparer来重用这种排序,我相信.Net中没有任何东西可以帮助你.但你可以用ComparerExtensions代替:

IComparer<string> comparer = KeyComparer<string>
    .OrderBy(a => NegativeToMaxValue(Array.IndexOf(new[] { "y", "x" }, a)))
    .ThenBy(a => a);
上一篇:python之高级编程


下一篇:英语四级词汇 Word List4