0

I have the following object:

public class Row
{
    public int Id {get; set;}
    public string Name {get; set;}
    public Dictionary<Column, Cell> Cells {get; set;} = new Dictionary<Column, Cell>();
}

public class Cell
{
    // ...
    public string Value {get; set;}
}

Having a List of Rows, how can I remove all duplicates (by comparing cell's values)?

I tried adding the following:

public class RowEqualitycomparer : IEqualityComparer<Row>
{
    public bool Equals(Row a, Row b)
    {
        return a.Cells.Equals(b.Cells);
    }
    
    public int GetHashCode(Row obj)
    {
        return obj.GetHashCode();
    }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • `Cells` is a dictionary, do you want to delete if they have the same reference or you want to delete it on some value? – FortyTwo Feb 14 '23 at 15:43
  • @FortyTwo I am trying to delete if the Cell's Cell Value is the same. – Sebastián Rubina Feb 14 '23 at 15:46
  • Trying to delete the row if all the cells in that row are the same as another row? – JBatstone Feb 14 '23 at 15:48
  • Think you have to get into it. Check the size of each, if equal, check the keys are all equal, if so, check that each cell value is equal. – JBatstone Feb 14 '23 at 15:49
  • 1
    `Cells` is a dictionary. So there are multiple entries for `Column` and for each `Column` there are multiple `Cells`. So on what condition you want to delete the `Row`? – FortyTwo Feb 14 '23 at 15:49
  • @FortyTwo So basically, I have a List of `Rows`. Each Row has a dictionary called `Cells`, which has a key which is the `Column` for each `Cell`, and a value which is the `Cell` object with it's own string `Value`. Within each `Row`, there are no repeated values, as each `Column` is different. What I want to check is if there are any `Row`s in which all `Cell`'s `Value`s are the same to another `Row`'s. What this is doing is exporting to an Excel sheet at the end of the whole process, but it is sometimes given duplicate rows as there are duplicate records and that's what I'm trying to prevent. – Sebastián Rubina Feb 14 '23 at 16:01
  • @SebastiánRubina You say: What I want to check is if there are any `Rows` in which all `Cell`'s `Value`s are the same to another `Row`'s. But `Value` belongs to `Cell` which is linked with `Column` not `Row`. Can you throw in an example to make it clear? Are 2 `Row`s same with different `Column` but the same `Cell`s? – FortyTwo Feb 14 '23 at 16:08
  • First off you need to indicate what `a.Cells.Equals(b.Cells)` means. This apparently checks for reference-equality, what isn't what you want. So you need to indicate how equality on a Dictionary should work - e.g. by providing an `IEqualityComparer`. Furthermore your hashcode-implementaion should reflect the properties being checked for equality. So in your case you should return `Cells.GetHashCode`, probably. – MakePeaceGreatAgain Feb 14 '23 at 16:12
  • It is unclear if you are asking for more than regular "compare dictionaries" behavior (which is covered in the duplicate I selected). Please edit the question to clarify why it is not the case (and obviously show that you know now how to compare dictionaries) if you still have a problem. – Alexei Levenkov Feb 14 '23 at 16:51
  • Side note: I removed the "asp.net" tag as I don't see anything specific to it either in the question or in any answer I can think of - if you find that tag important please [edit] the question to clarify why you need ASP.Net specific answers and in what way those answers should be related to ASP.Net. – Alexei Levenkov Feb 14 '23 at 16:53

1 Answers1

0

You can check cells in RowEqualitycomparer like this:

public bool Equals(Row? a, Row? b)
{
    if (a is null || b is null) return false;


    foreach (var cell in a.Cells)
    {
        var findItem = b.Cells[cell.Key]; // cell.Key is name 
        if (findItem is null) return false; // conflict in any column

        if (findItem.Value != cell.Value.Value) return false; // c.Value is Cell 
    }

    return true; 
}
thisisnabi
  • 1,045
  • 9
  • 21
  • Good start, but it does not address the possibility that `b` has _more_ cells than `a`. In that case equality would not be reflexive and could cause problems (i.e. a is equal to b but b is not equal to a. – D Stanley Feb 14 '23 at 17:28
  • Also it would throw an exception (not return `null`) if the key was not found - that's easy to fix by using `TryGetValue` – D Stanley Feb 14 '23 at 17:30