Question

I have a Sorted Dictionary that I want to Sort By Key Length.

Dictionary is defined as:

private SortedDictionary<String, String> _replacementDictionary;

and initialised as:

_replacementDictionary = new SortedDictionary<string, string>(new LengthComparer());

I thought I could use a Custom Sort like this:

class LengthComparer : IComparer<String>
{
    public int Compare(string x, string y)
    {
        return x.Length.CompareTo(y.Length);
    }
}

But this doesn't work for keys that are the same length. i.e. If I add keys "abc" and "xyz", only one of these shows when I enumerate the dictionary

Was it helpful?

Solution

If you mean you want to sort by length, then the key itself as a string, try:

class LengthComparer : IComparer<String>
{
    public int Compare(string x,string y)
    {
        int lengthComparison=x.Length.CompareTo(y.Length)
        if(lengthComparison==0)
        {
           return x.CompareTo(y);
        }
        else
        {
           return lengthComparison;
        }
    }
 }

What this code does is this: It makes a comparison based on length. If the two strings are tied for length, then it resolves the tie by comparing the strings themselves, not their length. You need to resolve this tie because of the reason @Adriano gave in his comment.

OTHER TIPS

List<KeyValuePair<string, string>> list = _replacementDictionary.ToList();

list.Sort((firstPair, nextPair) =>
    {
        return firstPair.Key.Length.CompareTo(nextPair.Key.Length);
    }
);

_replacementDictionary = list.ToDictionary(pair => pair.Key, pair => pair.Value);

You haven't specified that you wanted to continue down the route of IComparer so I hope this code is still suitable. You can wrap it in an extension if needs be.

Note: I can't try and compile it at the moment so may need cleaning up a bit.

Here is what I use.

using System.Collections.Generic;

public class KeyLengthSortedDictionary : SortedDictionary<string, string>
{
    public int Compare(string x, string y)
        {
            if (x == null) throw new ArgumentNullException(nameof(x));
            if (y == null) throw new ArgumentNullException(nameof(y));
            var lengthComparison = x.Length.CompareTo(y.Length);
            return lengthComparison == 0 ? string.Compare(x, y, StringComparison.Ordinal) : lengthComparison;
        }

    public KeyLengthSortedDictionary() : base(new StringLengthComparer()) { }   
}

Here is a demo : https://dotnetfiddle.net/plmFLL

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top