3

I have a piece of code here:

var grouped = nonGrouped.GroupBy(x => new
{
    x.Id,
    x.Col1,
    x.Col2
}).Select(x => new MyDbTable
{
    Id = x.Key.Id,
    VALUE = x.Sum(y => y.Value),
    Col1 = x.Key.Col1,
    Col2 = x.Key.Col2
}).ToList();

//Filter out rows with the same Col1/Col2 combination
var dbTableList = new List<MyDbTable>();
grouped.ForEach(x =>
{
    if (!dbTableList.Any(a => a.Col1 == x.Col2 && a.Col2 == x.Col1))
    {
        dbTableList.Add(x);
    }
});

I would like to remove the code under the comment "//Filter out rows with the same Col1/Col2 combination" and somehow add this functionality to my LINQ statement above the comment

Zoe
  • 27,060
  • 21
  • 118
  • 148
Bob
  • 4,236
  • 12
  • 45
  • 65
  • 2
    `a.Col1 == x.Col2` you should compare `Col1` with `Col1` – fubo Jun 08 '18 at 10:54
  • Possible duplicate of [Remove duplicates in the list using linq](https://stackoverflow.com/questions/1606679/remove-duplicates-in-the-list-using-linq) – SᴇM Jun 08 '18 at 10:57
  • 3
    Why not just call `Distinct()` before `ToList()`? It should work especially with the custom fields returned in `Select()`. – ViRuSTriNiTy Jun 08 '18 at 10:58
  • 1
    Do you need `Id`? Because your logic actually removes rows which are not duplicate because they have different `Id`. If you don't need `Id`, you can completely remove it, and you won't have duplicates anymore – Darjan Bogdan Jun 08 '18 at 10:58
  • 1
    Do you _really_ only want to add the 1st id (and its _sum_) for each col combo, if so you can group by the cols only, Distinct(), and take the 1st ID and the Sum for that id. – tolanj Jun 08 '18 at 11:01

4 Answers4

0

Can't you just do this?

var grouped = nonGrouped.GroupBy(x => new
            {
                x.Id,
                x.Col1,
                x.Col2
            }).Select(x => new MyDbTable
            {
                Id = x.Key.Id,
                VALUE = x.Sum(y => y.Value),
                Col1 = x.Key.Col1,
                Col2 = x.Key.Col2
            }).Where(z => z.Col1 != z.Col2).ToList();

or did I misunderstand your question entirely? It has happened before :)

Morten Bork
  • 1,413
  • 11
  • 23
0

I think you are looking for custom distinct values of grouped List

class MyDbTableComparer : IEqualityComparer<MyDbTable>
{
    public bool Equals(MyDbTable x, MyDbTable y)
    {
        if (x.Col1 == y.Col2 && x.Col2 == y.Col1) return true;
        return false;
    }
}

and after that, change upper statement to this:

.Select(x => new MyDbTable
{
    Id = x.Key.Id,
    VALUE = x.Sum(y => y.Value),
    Col1 = x.Key.Col1,
    Col2 = x.Key.Col2
}).ToList().Distinct(new MyDbTableComparer());

but I don't know whether it would work fine if you use Distinct() before ToList()

Muhammad Vakili
  • 708
  • 4
  • 19
0
nonGrouped
    .GroupBy(x => new { x.Col1, x.Col2 })
    .Where(group => !group.Take(1).Any())
    .SelectMany(group => group)
    .GroupBy(x => x.Id, x.Col1,x.Col2);

might work.

Not sure why you what the logic here is though (and why grouping by Id, Col1 and Col2 is neccesary if you want to remove all rows with equal col1 and col2 anyway).

brijber
  • 711
  • 5
  • 17
0

This should work nicely for you:

var dbTableList =
    nonGrouped
        .GroupBy(x => new
        {
            x.Id,
            x.Col1,
            x.Col2
        })
        .Select(x => new MyDbTable
        {
            Id = x.Key.Id,
            VALUE = x.Sum(y => y.Value),
            Col1 = x.Key.Col1,
            Col2 = x.Key.Col2
        })
        .GroupBy(x => new
        {
            x.Col1,
            x.Col2
        })
        .SelectMany(xs => xs.Take(1))
        .ToList();

The key to making this work is the GroupBy/SelectMany/Take(1) combo.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172