【问题标题】:Can I use Linq to create a comparer for a C# sorted dictionary我可以使用 Linq 为 C# 排序字典创建比较器吗
【发布时间】:2014-02-28 07:20:55
【问题描述】:

有没有使用 Linq 创建 SortedDictionary 的方法?这将避免创建比较器类的不便(和代码膨胀)。

例如,创建一个按字符串键反面排序的字典:

//NOT VALID SYNTAX
SortedDictionary<string, int> sortDict = new SortedDictionary(kvp => new String(kvp.Key.Reverse().ToArray());

//VALID SYNTAX
SortedDictionary<string, int> sortDict = new SortedDictionary<string, int>(new ReverseStringComparer);

private class ReverseStringComparer: IComparer<String>
{
    public int Compare(string x, string y)
    {
        string s1 = new string(x.Reverse().ToArray());
        string s2 = new string(y.Reverse().ToArray());
        return s1.CompareTo(s2);
    }
}

【问题讨论】:

  • 为什么不使用 Jon Skeet 的 ReverseComparer&lt;T&gt; 效率更高?
  • 建议的 ReverseStringComparer 类反转每个字符串,然后比较它们。 Jon Skeet 的版本只是颠倒了排序顺序。
  • @TimSchmelter 我认为 OP 在排序之前会反转字符串,而不是按相反的顺序排序。
  • 我不会为了使用 LINQ 而尝试使用 LINQ。它只是一个工具,在适当的时候使用它。在我看来,这几行代码几乎不能算作代码膨胀。
  • LINQ 不会创建比较器。但LINQ 方法(如 OrderBy)可以使用 Comparers。

标签: c# sorting dictionary icomparer


【解决方案1】:

您可以定义一个通用比较器类,对您要比较的项目应用提取函数:

public class KeyComparer<TItem, TKey> : Comparer<TItem>
{
    private readonly Func<TItem, TKey> extract;
    private readonly IComparer<TKey> comparer;

    public KeyComparer(Func<TItem, TKey> extract)
        : this(extract, Comparer<TKey>.Default)
    { }

    public KeyComparer(Func<TItem, TKey> extract, IComparer<TKey> comparer)
    {
        this.extract = extract;
        this.comparer = comparer;
    }

    public override int Compare(TItem x, TItem y)
    {
        // need to handle nulls
        TKey xKey = extract(x);
        TKey yKey = extract(y);
        return comparer.Compare(xKey, yKey);
    }
}

我通常使用这个类来提取属性;但是,您可以定义任何函数,例如字符串反转:

SortedDictionary<string, int> sortDict = new SortedDictionary<string, int>(
    new KeyComparer<string, string>(s => new string(s.Reverse().ToArray())));

更新:我在blog post 中更详细地介绍了这个比较器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多