7

Please bear with me if you think I haven't done enough research before asking

Problem Just came across a business requirement where we have to make sure the values in a dictionary are unique. i.e., We should filter a dictionary and the result of such filtering should have key value pairs with unique values.

BTW, it is a simple Dictionary with string values and string keys. To clarify more, below are the sample input and expected output values -
sourceDictionary would have values like below (just for the sake of representation of data, not syntactically correct) - { {"Item1", "Item One"}, {"Item11", "Item One"}, {"Item2", "Item Two"}, {"Item22", "Item Two"} } for this input, filteredDictionary should look like below - { {"Item1", "Item One"}, {"Item2", "Item Two"} }

Solution I proposed that is working

    var sourceDictionary = serviceAgent.GetSampleDictionary(); // Simplified for brevity  
    var filteredDictionary =  
        sourceDictionary.GroupBy(s => s.Value)  
            .Where(group => @group.Any())  
            .Select(g => g.First())  
            .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);  

Question Am I making too much logic into it? OR, putting it in other words, is there a simpler way to do this?

4

4 回答 4

7

This line:

.Where(group => @group.Any()) 

is unnecessary, as you won't get any empty groups anyway. (Also not sure what the '@' is for.)

Other than that, there's not really a simpler way to do this.

于 2013-01-03T12:19:35.733 回答
3

Your method works, but it's not extremely readable. If you create your class this way:

class DictionaryValueComparer<T1, T2> : IEqualityComparer<KeyValuePair<T1, T2>>
{
    public bool Equals(KeyValuePair<T1, T2> x, KeyValuePair<T1, T2> y)
    {
        return x.Value.Equals(y.Value);
    }

    public int GetHashCode(KeyValuePair<T1, T2> obj)
    {
        return obj.Value.GetHashCode();
    }
}

Then you can reduce your method to:

dictionary = dictionary.Distinct(new DictionaryValueComparer<int, string>()).
    ToDictionary(p => p.Key, p => p.Value);
于 2013-01-03T12:23:59.433 回答
0

Why not use the Linq extension method .Distinct()?

于 2013-01-03T12:19:14.190 回答
0

Assuming that it's not a custom type(then you need to implement IEqualityComparer<YourType> and pass it to Distinct)

var distinctDict = sourceDictionary
    .ToDictionary(kv => kv.Key, kv => kv.Value.Distinct());

Demo

var sourceDictionary=new Dictionary<string, List<string>>();
sourceDictionary.Add("A", new List<string>() { "A", "A", "B"});
sourceDictionary.Add("B", new List<string>() { "C", "D", "D" });

var distinctDict = sourceDictionary.ToDictionary(kv => kv.Key, kv => kv.Value.Distinct());
foreach(var kv in distinctDict)
    Console.WriteLine("Key:{0} Values:{1}", kv.Key, string.Join(",", kv.Value));
    // "A", "B" and "C", "D"
于 2013-01-03T12:20:04.857 回答