实现自定义IComparer

实现自定义IComparer

本文介绍了实现自定义IComparer<> (带有示例)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚编写了以下代码,该代码将按其本机string.Compare()对字符串进行排序,但允许一组异常(在本例中为customPriority),这些异常将优先于默认的string.Compare()函数.

Ive just written the following code, which will order strings by their native string.Compare() but allow a collection of exceptions (in this case customPriority) that will place priority over the default string.Compare() function.

这似乎有些漫长,我想知道.NET中是否内置某些东西可以允许这样做?

It all seems a bit long winded, I was wondering if there was something built into .NET to allow this?

    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);

        }
    }
}

推荐答案

首先,我认为重述该问题很有用:您希望通过以下方式进行排序:

First, I think it's useful to restate the problem: You want to sort by:

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

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

That means you can achieve your sort order by using OrderBy() for the first condition followed by ThenBy() for the second one:

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. (执行此操作的一种骇人听闻且难以理解的方法是将IndexOf()的结果直接转换为uint.)

NegativeToMaxValue() is necessary, because items not in the array should be last, but they would be first normally, because the index is -1. (A hackish and unreadable way to do the same would be to directly cast the result of IndexOf() to uint.)

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

If you wanted to reuse this sorting by creating an IComparer, I believe there is nothing in .Net to help you with that. But you could use ComparerExtensions instead:

IComparer<string> comparer = KeyComparer<string>
    .OrderBy(a => NegativeToMaxValue(Array.IndexOf(new[] { "y", "x" }, a)))
    .ThenBy(a => a);

这篇关于实现自定义IComparer&lt;&gt; (带有示例)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 02:36