1

For example, I have a list of excel cells

List<Cell> cells = new List<Cell>
{
   new Cell("4"),
   new Cell("Hez"),
   new Cell("Method"),
   new Cell("4"),
   new Cell("Val"),
   new Cell("Method"),
}

I need to get the only unique cell (in this case Cell("Val"), Cell("Hez")) so Distinct() is not for me.

I found this solution but it doesn't return any data at all

var uniqueTest = allData.GroupBy(cell => cell)
                        .Where(group => group.ToString().Count() == 1)
                        .Select(group => group.Key);

I think the problem is Cell object doesn't contain any comparison methods (This is IronXl lib) so this is why I'm using ToString() here.

But I don't quite understand linq yet, so any explanation or advice is appreciated

Remarks:

I need to get a list of cells back, but with unique values

Skyglar
  • 135
  • 3
  • 12

4 Answers4

3

Step 1: Group the cells by their value.
Step 2: Keep only the groups of size 1.
Step 3: Get the only item from each group.

var uniqueCells =
    allData.GroupBy(cell => cell.Value) //Step 1
    .Where(g => g.Count() == 1) //Step 2
    .Select(g => g.Single()) //Step 3
Dennis_E
  • 8,751
  • 23
  • 29
  • This is by far the simplest solution, use this if it is enough for you! But if you _often_ have to group or compare `Cell` objects, you could implement a custom `IEqualityComparer`. See https://stackoverflow.com/a/60714143 – gnud Feb 15 '21 at 15:06
0

This should be easy.

Lets count the value of Number 4 is Key.. then your linq should look like this

var uniqueTest = allData.GroupBy(x=> x.Key).Select(x=> x.First()).Select(x=> x.Key);
Alen.Toma
  • 4,684
  • 2
  • 14
  • 31
0

If I understand you correctly, and i'm not sure if I do, you can use .First() or the more robust .Single()

var uniqueTest = allData.First(c => c.ToString() == "Val");

In this sample i'm assuming c.ToString() will give you the cell's value. Otherwise it will likely be something like c.Value or something.

There are als the OrDefault variants. Check out this article for the differences; https://www.c-sharpcorner.com/blogs/singleordefault-vs-firstordefault-in-linq-query1

sommmen
  • 6,570
  • 2
  • 30
  • 51
0

if you class Cell is something like this.

    public class Cell
    {
        public Cell(string mystring)
        {
            MyString = mystring;
        }
        public string MyString { get; set; }
 

then this will work to get a unique list:

        List<Cell> UniqueCells = new List<Cell>();

        foreach (var cell in cells)
        {
            if(!UniqueCells.Any(c=>c.MyString == cell.MyString))
            {
                UniqueCells.Add(cell);
            }
        }
    

In this case only the first cell containing 'Method' and '4' will be added. the '!' and '.Any' are the essential parts.

Visualcoach
  • 111
  • 1
  • 5