Domanda

Is there a way of creating a SortedDictionary using Linq? This would avoid the inconvenience (and code bloat) of creating a comparer class.

For example, create a dictionary sorted on the reverse of the string key:

//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);
    }
}
È stato utile?

Soluzione

You can define a generic comparer class that applies an extraction function over the items you want to compare:

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

I usually use this class for extracting properties; however, you could define any function, such as your string reversal:

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

Update: I have covered this comparer in more detail in my blog post.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top