What C# Data Structure Should I Use?
This question pertains to C#, LINQ grouping and Collections.
I'm currently working on a grouping issue and I wanted to get some feedback from the community. I've encountered this particular problem enough times in the past that I'm thinking of writing my own data structure for it. Here are the details:
Suppose you have a grouping that consists of a manufacturer and products and the data structure is grouped by manufacturer. There are many manufacturers and many products. The manufacturers each have a unique name and id. The products may have similar names, but they do have unique ids. The proceeding list represents an example.
Ford 1, Fiesta 1945, Taurus 6413, Fusion 4716, F1 8749,
Toyota 2, Camry 1311, Prius 6415, Corolla 1117, Tacoma 9471
Chevrolet 3, Silverado 4746, Camero 6473, Volt 3334, Tahoe 9974
etc...
The data structure I would use to represent this would be
IEnumerable<Manufacturer, ManufacturerID, IEnumerable<Product, ProductID>>
but this doesn't exist. So my question I want to ask the community is what data structure would you recommend and why?
Update:
I would like to keep the types anonymous and avoid the dynamic keyword. So the data structure would be something like
IEnumerable SomeDataStructure<T, U, V>
The other requirement is that is can have duplicated items. Here's kind of what I'm thinking:
public class MyDataStructure<T, U, V>
{
// make this like a list, not a dictionary
}
Update:
I decided to go with a Tuple data structure. It's very powerful and easy to query against. The proceding code is how I ended up using it to create my manufacturer-vehicle relationships. The result is a nicely ordered data structure that has unique manufacturers ordered by name with their associated unique vehicles ordered by name.
public class ManufacturersVehicles
{
public int ManufacturerID { get; set; }
public string ManufacturerName { get; set; }
public int VehicleID { get; set; }
public string VehicleName { get; set; }
}
// "data" actually comes from the database. I'm just creating a list to use a mock structure to query against.
var data = new List<ManufacturersVehicles>
{
{ ManufacturerID = 1, Manufacturer = "Ford", VehicleID = 1945, VehicleName = "Fiesta" },
{ ManufacturerID = 1, Manufacturer = "Ford", VehicleID = 6413, VehicleName = "Taurus" },
{ ManufacturerID = 1, Manufacturer = "Ford", VehicleID = 4716, VehicleName = "Fusion" },
etc...
};
// Get a collection of unique manufacturers from the data collection and order it by the manufacturer's name.
var manufacturers = data.Select(x => new { ManufacturerID = x.ManufacturerID, ManufacturerName = x.ManufacturerName })
.Distinct()
.OrderBy(x => x.ManufacturerName)
.Select(x => Tuple.Create(x.ManufacturerID, x.ManufacturerName, new Dictionary<int, string>()))
.ToList();
// Add the manufacturer's vehicles to it's associated dictionary collection ordered by vehicle name.
foreach (var manufacturer in manufacturers)
{
// Get the collection of unique vehicles ordered by name.
var vehicles = _alertDetails.Where(x => x.ManufacturerID == manufacturer.Item1)
.Select(x => new { VehicleID = x.VehicleID, VehicleName = x.VehicleName })
.Distinct()
.OrderBy(x => x.VehicleName);
foreach (var vehicle in vehicles)
{
manufacturer.Item3.Add(vehicle.开发者_运维百科VehicleID, vehicle.VehicleName);
}
}
I would create a class named Manufacturer:
public class Manufacturer
{
public int ManufacturerId { get; set;}
public string Name { get; set; }
public IEnumerable<Product> Products { get; set;}
}
Then create a Product class:
public class Product
{
public int ProductId { get; set;}
public string Name { get; set;}
}
Then use LINQ projection with the Select extension method to create the Manufacturer object.
Like this?
public class Manufacturer : IEquatable<Manufacturer>
{
public string Name { get; private set; }
public int ID { get; private set; }
// ...
}
public class Product
{
public string Name { get; private set; }
public int ID { get; private set; }
// ...
}
// groups is of type IEnumerable<IGrouping<Manufacturer, Product>>
var groups = data.GroupBy(row => new Manufacturer(row), row => new Product(row));
EDIT: If you want to use anonymous types (as you mentioned now in your update) then GroupBy
should work just as well if you construct anonymous objects, instead of declaring a Manufacturer
and Product
class as in my sample.
MyDataStructure
sounds very similar to a Tuple
. See here for the three-generic parameter variant. Tuple
gives a strongly typed container for a number of specified other types.
精彩评论