Reputation: 83
Suppose I have a dictionary<int, string> like this
dict1 = {{[4,bcefgh]},{[5,abcefgh]},{[6,efgh]},{[7,bcefgh]},{[10,cefghi]}}
I want to sort pairs in this dictionary according to length of string values, without using extra loops. That is, results should be:
dict1 = {{[6,efgh]},{[4,bcefgh]},{[7,bcefgh]},{[10,cefghi]},{[5,abcefgh]}}
My initial answer was to create a separate dictionary that had the same keys and length of every corresponding string and a third dictionary that loops over pair as follows:
foreach (KeyValuePair<int,string> pair in dict1)
{
temp_dict.Add(pair.Key, pair.Value.Count());
}
var items = from pair in temp_dict
orderby pair.Value ascending
select pair;
foreach (KeyValuePair<int, int> pair in items)
{
result_dict.Add(pair.Key, dict1[pair.Key]);
}
But this result is now practical with large set of data.
Upvotes: 2
Views: 2110
Reputation: 3968
Here is what I use. A sorted set of key value pairs. Ordered by value length.
public class ValueSortedKeyValuePairSet : SortedSet<KeyValuePair <int, string>>
{
private class StringLengthComparerDecending : IComparer<KeyValuePair <int, string>>
{
public int Compare(KeyValuePair <int, string> x, KeyValuePair <int, string> y)
{
var lengthComparison = x.Value.Length.CompareTo(y.Value.Length);
return lengthComparison == 0 ? string.Compare(x.Value, y.Value, StringComparison.Ordinal) : lengthComparison;
}
}
public ValueSortedKeyValuePairSet() : base(new StringLengthComparerDecending()) {}
public ValueSortedKeyValuePairSet(IEnumerable<KeyValuePair <int, string>> e) : base(e, new StringLengthComparerDecending()) {}
}
}
Demo: https://dotnetfiddle.net/pklISX
Upvotes: 0
Reputation: 37060
If you can live with an IOrderedEnumerable of KeyValuePairs, this will work:
var dict1 = new Dictionary<int, string>
{
{4, "bcefgh"},
{5, "abcefgh"},
{6, "efgh"},
{7, "bcefgh"},
{10, "cefghi"}
};
IOrderedEnumerable<KeyValuePair<int, string>> sortedDict =
dict1.OrderBy(i => i.Value.Length).ThenBy(i => i.Key);
foreach (var keyValuePair in sortedDict)
{
Console.WriteLine(keyValuePair.Key + ": " + keyValuePair.Value);
}
// Output:
// 6: efgh
// 4: bcefgh
// 7: bcefgh
// 10: cefghi
// 5: abcefgh
Upvotes: 4
Reputation: 6016
You can't count on Dictionary being sorted. Instead you can use SortedDictionary<string, string>
and pass its constructor a custom IComparer<T>
.
Upvotes: 4