rawcoder
asked on
Linq: How to perform GroupBy when working with 3 or more columns
I start off with the following list
List items = new List();
items.add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 2, ModelName = "98 Regency" });
items.add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 3, ModelName = "88 Delta" });
items.add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 4, ModelName = "Alero" });
items.add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 5, ModelName = "442" });
items.add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 11, ModelName = "Skylark" });
items.add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 13, ModelName = "Electra 225" });
items.add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 14, ModelName = "Regal" });
items.add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 16, ModelName = "Enclave" });
But would like it converted to the following format:
List newList = new List();
items.add(new VehicleWithModelList { MakeID = 1, MakeName = "Oldsmobile", new List<Model> () { This list would contain the 4 oldsmobile models from above}});
items.add(new VehicleWithModelList { MakeID = 2, MakeName = "Buick", new List<Model> () { This list would contain the 4 buick models from above}});
I have the following linq to object query but I keep getting syntax errors stating it expects a semicolon before the last close parenthesis.
var newList = items.GroupBy(x => new {x.MakeID, x.ModelID, x.MakeName, x.ModelName}, (key, group) => new { MakeID = key.MakeID, MakeName = key.MakeName, ModelList = group.Select(z => new Model { ModelID = z.ModelID, ModelName = z.ModelName })).Cast< VehicleWithModelList >();
What would be the correct way to accomplish this?
List items = new List();
items.add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 2, ModelName = "98 Regency" });
items.add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 3, ModelName = "88 Delta" });
items.add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 4, ModelName = "Alero" });
items.add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 5, ModelName = "442" });
items.add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 11, ModelName = "Skylark" });
items.add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 13, ModelName = "Electra 225" });
items.add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 14, ModelName = "Regal" });
items.add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 16, ModelName = "Enclave" });
But would like it converted to the following format:
List newList = new List();
items.add(new VehicleWithModelList { MakeID = 1, MakeName = "Oldsmobile", new List<Model> () { This list would contain the 4 oldsmobile models from above}});
items.add(new VehicleWithModelList { MakeID = 2, MakeName = "Buick", new List<Model> () { This list would contain the 4 buick models from above}});
I have the following linq to object query but I keep getting syntax errors stating it expects a semicolon before the last close parenthesis.
var newList = items.GroupBy(x => new {x.MakeID, x.ModelID, x.MakeName, x.ModelName}, (key, group) => new { MakeID = key.MakeID, MakeName = key.MakeName, ModelList = group.Select(z => new Model { ModelID = z.ModelID, ModelName = z.ModelName })).Cast< VehicleWithModelList >();
What would be the correct way to accomplish this?
Do you have a custom List type? I'd expect List<Vehicle> here...
Any way, I'd do it like this:
List<Vehicle> olds = new List<Vehicle>();
olds.Add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 2, ModelName = "98 Regency" });
olds.Add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 3, ModelName = "88 Delta" });
olds.Add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 4, ModelName = "Alero" });
olds.Add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 5, ModelName = "442" });
List<Vehicle> buicks = new List<Vehicle>();
buicks.Add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 11, ModelName = "Skylark" });
buicks.Add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 13, ModelName = "Electra 225" });
buicks.Add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 14, ModelName = "Regal" });
buicks.Add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 16, ModelName = "Enclave" });
List<Vehicle> all = olds.Concat(buicks).ToList();
List<VehicleWithModelList> byHand = new List<VehicleWithModelList>();
byHand.Add(new VehicleWithModelList { MakeID = 1, MakeName = "Oldsmobile", ModelList = olds });
byHand.Add(new VehicleWithModelList { MakeID = 2, MakeName = "Buick", ModelList = buicks });
IEnumerable<VehicleWithModelList> byGrouping = from x in all group x by x.MakeID into g
select new VehicleWithModelList { MakeID = g.Key, MakeName = g.First().MakeName, ModelList = g.ToList()};
Note the byHand is just putting the list together manually, byGrouping uses the LINQ group construction. This requires MakeID and MakeName to be in lockstep, since it just uses the first MakeName found for the group...true in your example data.
Hi jensfiederer;
See if this fits your needs.
See if this fits your needs.
// Class level variable with original list
private List<Vehicle> items = new List<Vehicle>();
// Created original list of data
items.Add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 2, ModelName = "98 Regency" });
items.Add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 3, ModelName = "88 Delta" });
items.Add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 4, ModelName = "Alero" });
items.Add(new Vehicle { MakeID = 1, MakeName = "Oldsmobile", ModelID = 5, ModelName = "442" });
items.Add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 11, ModelName = "Skylark" });
items.Add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 13, ModelName = "Electra 225" });
items.Add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 14, ModelName = "Regal" });
items.Add(new Vehicle { MakeID = 2, MakeName = "Buick", ModelID = 16, ModelName = "Enclave" });
// Using Linq to Object to covert to a new format
var newList = from v in items
group v by new {v.MakeID, v.MakeName}
into vehicleGroup
select new VehicleWithModelList()
{
MakeID = vehicleGroup.Key.MakeID,
MakeName = vehicleGroup.Key.MakeName,
VehicleList = vehicleGroup.ToList()
};
// Class object used in original list
public class Vehicle
{
public int MakeID { get; set; }
public string MakeName { get; set; }
public int ModelID { get; set; }
public string ModelName { get; set; }
}
// Class object used to covert from old to new format
public class VehicleWithModelList
{
private List<Vehicle> _vehicleList = new List<Vehicle>();
public int MakeID { get; set; }
public string MakeName { get; set; }
public List<Vehicle> VehicleList
{
get { return _vehicleList; }
set { _vehicleList = value; }
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Sorry my original post was to be directed to the question author rawcoder.