Click here to Skip to main content
15,886,873 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have an array of Products, a custom POCO. Some of these products refer to the same item. Some will have the TariffUnrestricted price and another will have the StandingChargePenceDay . I need to merge these together.

I am trying to group the products together, then select out the key and the values for each product. I think the code will explain better:

C#
public override Product[] Import(string path, Func<Worksheet, bool> worksheetSelector = null)
{
    Product[] products = base.Import(path, worksheetSelector);

    var groups = products.GroupBy(p => new Product
    {
        PlanName = p.PlanName,
        RateType = p.RateType,
        ContractDuration = p.ContractDuration,
        Duration = p.Duration,
        TariffDescription = p.TariffDescription,
        //TariffUnrestricted = p.TariffUnrestricted,
        //StandingChargePenceDay = p.StandingChargePenceDay
    });

    products = groups.Select(g =>
    {
        Product product = g.Key;
        product.TariffUnrestricted = g.Max(p => p.TariffUnrestricted);
        product.StandingChargePenceDay = g.Max(p => p.StandingChargePenceDay);
        return product;
    }).ToArray();

    return products;
}


The items do not merge. The number of groups is always the same as the number of products (1:1).

I tried making the Product IComparable<Product>, IComparer<Product>, IEquatable<Product> but nothing works?

My google-fu is week. I cannot find the correct terms :C

What am I doing wrong?

Thanks
Andy
Posted

1 solution

Why are you trying to group by a new product? All that will do is attempt to group by the reference value itself, won't it? Which would explain the 1:1 correlation between groups and products. :laugh:
Don't you want something like:
C#
var groups = products.GroupBy(p => p.TariffDescription);
or similar?

[edit]
A quick test:
C#
public class MyClass
    {
    public int Value { get; set; }
    public string Name { get; set; }
    }

And
C#
List<MyClass> list = new List<MyClass>();
MyClass a = new MyClass() { Value = 1, Name = "A" };
MyClass b = new MyClass() { Value = 1, Name = "B" };
MyClass c = new MyClass() { Value = 2, Name = "C" };
MyClass d = new MyClass() { Value = 2, Name = "D" };
MyClass e = new MyClass() { Value = 3, Name = "E" };
list.Add(a);
list.Add(b);
list.Add(c);
list.Add(d);
list.Add(e);
var g1 = list.GroupBy(m => m.Value);
var g2 = list.GroupBy(m => new MyClass { Value = m.Value, Name = m.Name });
Console.WriteLine(g1.Count() + ":" + g2.Count());

Gives "3:5"

Adding the IEquatable interface doesn't change that either:
C#
public class MyClass : IEquatable<MyClass>
    {
    public int Value { get; set; }
    public string Name { get; set; }
    public bool Equals(MyClass other)
        {
        return Value == other.Value;
        }
    }
I still get 3:5

[/edit]
 
Share this answer
 
v2
Comments
Andy Lanng 7-Jan-16 12:19pm    
But what's wrong with grouping by the ref value? is it a restriction?
OriginalGriff 7-Jan-16 12:24pm    
There's nothing *wrong* with it - it's just that they will all by definition be different... :laugh:
Andy Lanng 7-Jan-16 12:26pm    
Hmm, I /think/ I get it, but I thought that IEquatable meant that I was dictating that they /are/ the same.

It works with new instead of Product. Wouldn't that have the same issue O_o
OriginalGriff 7-Jan-16 12:47pm    
Doesn't look like it - I just tried a quick test and modified the answer
OriginalGriff 7-Jan-16 12:50pm    
Just added a quick mod to my test:
var g2 = list.GroupBy(m => new MyClass { Value = m.Value, Name = m.Name } .Value);
That gives "3:3" with or without the IEquatable interface.

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