Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return IGrouping from Linq query when grouping

I am adding a bunch of different parts to a List<> and some of the part may have the same part number and the same length. If they do have the same partnumber and the same length I need to group those parts for displaying.

When they're grouped I need to show that partnumber and how many of that partnumber with a specific length.

I am needing to know how to group with two differnt properties and return eaigher a typed object with that List<ICutPart> and the total of

Below is as far as I could get, I was attempting to return (IGrouping<int,ICutPart>)sGroup; but I am getting an error at the return portion of the function body.

How can I return a typed object with Group{List<ICutPart> Parts, Int Total}?

    public class CutPart : ICutPart
{
    public CutPart() { }
    public CutPart(string name, int compID, int partID, string partNum, decimal length)
    {
        this.Name = name;
        this.PartID = partID;
        this.PartNumber = partNum;
        this.CompID = compID;
        this.Length = length;
    }
    public CutPart(string name, int compID, int partID, string partNum, decimal width, decimal height)
    {
        this.Name = name;
        this.CompID = compID;
        this.PartNumber = partNum;
        this.PartID = partID;
        this.Width = width;
        this.Height = height;
        this.SF = decimal.Parse(((width / 12) * (height / 12)).ToString(".0000")); //2dp Number;
    }

    public string Name { get; set; }
    public int PartID { get; set; }
    public string PartNumber { get; set; }
    public int CompID { get; set; }
    public decimal Length { get; set; }
    public decimal Width { get; set; }
    public decimal Height { get; set; }
    public decimal SF { get; set; }
}

public class CutParts : List<ICutPart>
{

    public IGrouping<int, ICutPart> GroupParts()
    {

        var sGroup = from cp in this
                     group cp by cp.Length into g
                     select new
                     {
                         CutParts = g,
                         total = g.Count() 
                     };

        return (IGrouping<int, ICutPart>)sGroup;

    }


    public new void Add(ICutPart item)
    {
        base.Add(item);
    }

}
like image 451
Filling The Stack is What I DO Avatar asked Dec 27 '22 06:12

Filling The Stack is What I DO


1 Answers

I guess you want to create a bunch of group objects where each group object has the common Length and the bunch of ICutParts that have that length.

In code, it looks something like this:

public IEnumerable<IGrouping<int, ICutPart>> GroupParts()
{
  return this.GroupBy( o => o.Length );
}

That probably needs explaining!


The IEnumerable bit is the collection of group objects - one for each distinct Length

Each "group object" in that collection is an IGrouping<int, ICutPart>.

This object has a Key property, which is the thing you grouped by - Length in this case.

It is also a collection as IGrouping<T> derives from IEnumerable<T> - it is the collection of ICutParts that have that length.

If you call ToList() on one of the group objects, you will get a List<ICutPart>


To make this easier for the caller, you could create a class to hold these values.

If you declared a class like this:

public class GroupedByLength
{
  public int Length { get; set; }
  public List<ICutPart> CutParts { get; set; }
}

then you could return a collection of these objects:

public List<GroupedByLength> GroupParts()
{
  return this
    .GroupBy( o => o.Length )
    .Select( g => new GroupedByLength
      {
        Length = g.Key,
        CutParts = g.ToList(),
      }
    )
    .ToList()
  ;
}
like image 141
Nick Butler Avatar answered Jan 05 '23 21:01

Nick Butler