Click here to Skip to main content
15,567,447 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello C# gurus and mavens. I have a question for you which I believe is actually a .GROUPBY() question.

I have a set of objects of type Cell. Each Cell has a property Candidates which is an ordered list of strings:
public List<string> Candidates { get; private set; }

I would like to group the Cells by their common Candidates (e.g. all Cells with candidates {"x", "y", "z"} in one group, those with {"x", "z"} into another, etc).

I coded something similar to the following:

cellGroupings = 
  allCells.Where(c => c.Candidates.Count > 0)
          .ToDictionary(g => g.Key, g => g);

So lets assume allCells has some set of cells:
{ Cell.Name = "1st", Cell.Candidates = { "x", "y", "z" } }
{ Cell.Name = "2nd", Cell.Candidates = { "x", "z" }      }
{ Cell.Name = "3rd", Cell.Candidates = { "x", "z" }      }
{ Cell.Name = "4th", Cell.Candidates = { "x", "y", "z" } }

The problem is that GroupBy() and/or ToDictionary() seems to be treating each list of candidates as not-equivalent to the other lists, despite them having the same Candidates. So, instead of the above generating two groupings (one for { "x", "y", "z" } a containing "1st" and "4th", and one for { "x", "z" } containing "2nd" and "3rd") it generates four groupings with 1 Cell each.

Is there some trick to getting two lists to appear equivalent to GroupBy() and/or ToDictionary()?

1 solution


The reason why it's not working is because GroupBy uses the reference equality comparer by default, so even though they contain the same string candidates in theory, they aren't actually equal.

What I did was convert each of the candidate lists into a direct string object like this:

var cellGroupings = allCells.Where(c => c.Candidates.Any()).GroupBy(c => String.Join(",", c.Candidates.ToArray())).ToDictionary(g=>g.Key, g=>g);

Hope it helps!
Share this answer

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900