Объединение результирующих наборов
Я пытаюсь создать список всех возможных комбинаций параметров/значений продукта для каждого продукта в каталоге. Каждый продукт может иметь переменное число опций, и каждая опция может иметь переменное число значений.
Так, например, скажем, у меня была рубашка, и параметр / значения были цвет (красный, желтый, синий), размер (s, m, l) и материал (хлопок, нейлон, смесь). Я хочу создать список, который выглядит следующим образом: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
Я знаю, что теоретически это могло бы породить много но на практике большинство продуктов имеют только два или три варианта с двумя или тремя значениями каждый.
Я работаю в C#, но любой пример кода был бы чрезвычайно полезен. Большое спасибо за любые предложения!
5 ответов:
Материал котловой плиты:
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; } }
Соответствующая часть:
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);
Или вы можете создать анонимный тип в последней строке:
select new { Colour = c, Size = s, Material = m };
Это может быть так просто, как:
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 }); } } }
Где
colours
,sizes
иmaterials
- это строковые массивы значений. Это то, чего вы ожидали?
Это на самом деле кросс-соединение, а не конкатенация.
Вы можете сделать это довольно просто в C#, используя LINQ или вложенные циклы foreach. Путь LINQ довольно прост для глаз. Предположим, что цвета, размеры и ткани уже существуют как коллекции в вашем коде.
from color in colors from size in sizes from fabric in fabrics select new { color, size, fabric }
Также рассмотрим:
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); }