Matt Wilko
Matt Wilko

Reputation: 27342

How to Sort a Dictionary by key string length

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

Upvotes: 0

Views: 3519

Answers (3)

herostwist
herostwist

Reputation: 3968

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

Upvotes: 0

user1017882
user1017882

Reputation:

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.

Upvotes: 0

Boluc Papuccuoglu
Boluc Papuccuoglu

Reputation: 2356

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.

Upvotes: 4

Related Questions