开发者

Concatenating result sets

I am trying to generate a list of all possible product option/value combinations for each product i开发者_如何学Cn a catalog. Each product can have a variable number of options, and each option can have a variable number of values.

So, for example say I had a shirt, and the option/values were color (red, yellow, blue), size (s, m, l), and material (cotton, nylon, blend). I want to generate a list that looks like this:

red, s, cotton
red, s, nylon
red, s, blend
red, m, cotton
red, m, nylon
red, m, blend
red, l, cotton
red, l, nylon
red, l, blend
yellow, s, cotton
yellow, s, nylon
yellow, s, blend
yellow, m, cotton
yellow, m, nylon
yellow, m, blend
yellow, l, cotton
yellow, l, nylon
yellow, l, blend
blue, s, cotton
blue, s, nylon
blue, s, blend
blue, m, cotton
blue, m, nylon
blue, m, blend
blue, l, cotton
blue, l, nylon
blue, l, blend

I know that in theory, this could generate a LOT of results, but in practice most of the products only have two or three options with two or three values each.

I'm working in C#, but any kind of code example would be extremely helpful. Thanks very much for any suggestions!


The boiler plate stuff:

public class Color
{
    private readonly string _color;

    public Color(string color)
    {
        _color = color;
    }

    public override string ToString()
    {
        return _color;
    }
}

public class Size
{
    private readonly string _size;

    public Size(string size)
    {
        _size = size;
    }

    public override string ToString()
    {
        return _size;
    }
}

public class Material
{
    private readonly string _material;

    public Material(string material)
    {
        _material = material;
    }

    public override string ToString()
    {
        return _material;
    }
}

The relevant part:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var colors = new List<Color>() { new Color("Red"), 
                                             new Color("Yellow"), 
                                             new Color("Blue") };

            var sizes = new List<Size>() { new Size("S"), 
                                           new Size("M"), 
                                           new Size("L") };

            var materials = new List<Material>() { new Material("Cotton"),
                                                   new Material("Nylon"),
                                                   new Material("Blend") };

            var products = from c in colors
                           from s in sizes
                           from m in materials
                           select new { Color = c, Size = s, Material = m };


            foreach (var p in products)
            {
                Console.WriteLine("{0}, {1}, {2}", p.Color, p.Size, p.Material);
            }
            Console.ReadKey(true);
        }
    }
}


var results =   from c in colours
                from s in sizes
                from m in materials
                select Tuple.Create(c, s, m);

or you could create an anonymous type in the last line:

select new { Colour = c, Size = s, Material = m };


It could be as simple as:

public class Product
{
  public string Colour { get; set; }
  public string Size { get; set; }
  public string Material { get; set; }
}

IList<Product> products = new List<Product>();
foreach (string colour in colours)
{
  foreach (string size in sizes)
  {
    foreach (string material in materials)
    {
      products.Add(new Product 
      {
        Colour = colour,
        Size = size,
        Material = material
      });
    }
  }
}

Where colours, sizes and materials are string arrays of the values. Is this what you were expecting?


This is actually a cross-join, not concatenation.

You could do this pretty simply in C# using LINQ or nested foreach loops. The LINQ way is pretty easy on the eyes. Assuming colors, sizes, and fabrics all exist as collections in your code already.

from color in colors
from size in sizes
from fabric in fabrics
select new {
    color,
    size,
    fabric
}


Also consider:

public enum Color    {Red, Yellow, Blue};
public enum Size     {S, M, L};
public enum Material {Cotton, Nylon, Blend};
public class Product
{
   public Color    color;
   public Size     size;
   public Material material;
}

List<Product> products = new List<Product>();

int numColors    = Enum.GetValues(typeof(Color)).Length;
int numSizes     = Enum.GetValues(typeof(Size)).Length;
int numMaterials = Enum.GetValues(typeof(Material)).Length;

for(int i = 0; i < numColors; i++)
   for(int j = 0; k < numSizes; j++)
       for(int k = 0; k < numMaterials; k++)
       {
          Product p  = new Product();
          p.color    = (Color)i;
          p.size     = (Size)j;
          p.material = (Material)k;
          products.Add(p);
       }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜