Question

I've got the following Dictionary:

Dictionary<int, int> myDict = new Dictionary<int, int>();
myDict.Add(0, 6);
myDict.Add(1, 10);
myDict.Add(2, 6);
myDict.Add(3, 14);
myDict.Add(4, 10);
myDict.Add(5, 10);

I already know how to get all the duplicates values:

var duplicatedValues = myDict.GroupBy(x => x.Value).Where(x => x.Count() > 1);

But what I want instead is the following: A list with all the keys of the duplicated values, but excluding the last duplicated ones. So in my list above the duplicates values are 10 and 6, and what I want is a list of the following keys: 0, 1, 4 (so excluding 2 and 5).

What is the best way to do this?

Any help would be appreciated. Thanks in advance.

EDIT: I did manage to do it with this piece of code by modifying something I found on the internet, but to be honest I find it a bit dumb to first create a string from the keys and then back into ints. I'm kinda new to the Aggregate-command, so any help how to modify the following code would be welcome:

var lookup = allIDs.ToLookup(x => x.Value, x => x.Key).Where(x => x.Count() > 1);

foreach (var item in lookup) {
    var keys = item.Aggregate("", (s, v) => s + "," + v);
    string[] split = keys.Split(',');
    for (int i = 0; i < split.Length - 1; i++) {
        if (!split[i].Equals("")) {
            Console.WriteLine("removing card nr: " + split[i]);
            CurrentField.removeCardFromField(Convert.ToInt32(split[i]));
        }
    }
}
Was it helpful?

Solution

This should do it:

var firstKeysOfDupeValues = myDict
    .GroupBy(x => x.Value)
    .SelectMany(x => x.Reverse().Skip(1))
    .Select(p => p.Key);
    .ToList();

After grouping by value, the last key for each value group is rejected using .Reverse().Skip(1) (this construct serves double duty: it also rejects the single keys of non-duplicated values) and the keys of the remaining key/value pairs are extracted into the result.

OTHER TIPS

You could use

var allButLastDupKeys = myDict.GroupBy(kv => kv.Value)
    .Where(g => g.Count() > 1)
    .SelectMany(g => g.Take(g.Count() - 1).Select(kv => kv.Key));
string dupKeys = string.Join(",", allButLastDupKeys); // 0,1,4
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top