Click here to Skip to main content
14,771,671 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:

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:
var groups = products.GroupBy(p => p.TariffDescription);
or similar?

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

And
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:
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]
   
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.
Andy Lanng 8-Jan-16 4:01am
   
I'm sure there is a way, but using an anon class works fine. Thanks for taking a look ^_^

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

  Print Answers RSS
Top Experts
Last 24hrsThis month



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