You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从属性选项列表生成所有唯一的Product变体?

生成全属性组合的Product变体列表

现有模型定义

PayloadItem 模型

internal class PayloadItem
{
    public string Attribute { get; set; }
    public string Option { get; set; }
}

Product 及 AttributeValue 模型

internal class Product
{
    public string Name { get; set; }
    public string Description { get; set; }
    public List<AttributeValue> AttributeValues { get; set; }
}

internal class AttributeValue
{
    public string Attribute { get; set; }
    public string Value { get; set; }
}

输入的属性选项列表

List<PayloadItem> items = new List<PayloadItem>()
{
    new PayloadItem{Attribute="Size",Option="S"},
    new PayloadItem{Attribute="Size",Option="M"},

    new PayloadItem{Attribute="Color",Option="Red"},
    new PayloadItem{Attribute="Color",Option="Green"},
    new PayloadItem{Attribute="Color",Option="Blue"},

    new PayloadItem{Attribute="Width",Option="100"},
    new PayloadItem{Attribute="Width",Option="200"},

    new PayloadItem{Attribute="Length",Option="10000"},
    new PayloadItem{Attribute="Length",Option="20000"},
    new PayloadItem{Attribute="Length",Option="30000"},
};

核心需求

  • 生成所有可能的Product对象列表,每个Product必须包含所有属性的一个取值
  • 任意两个Product的AttributeValues至少有一个属性值不同
  • Product的Name、Description等其他属性直接复用外部传入的对象属性,无需额外处理

实现方案

通过生成属性选项的笛卡尔积,再映射为Product对象来完成需求,具体步骤如下:

代码实现

// 1. 按属性名称分组,整理每个属性对应的所有可选值
var groupedAttributes = items
    .GroupBy(item => item.Attribute)
    .Select(g => new 
    {
        Attribute = g.Key,
        Options = g.Select(item => item.Option).ToList()
    })
    .ToList();

// 2. 生成所有属性选项的笛卡尔积组合
var attributeCombinations = GetCartesianProduct(groupedAttributes);

// 3. 映射为Product变体(假设外部主产品为externalProduct)
var externalProduct = new Product { Name = "示例产品", Description = "示例描述" };
var productVariants = attributeCombinations
    .Select(combination => new Product
    {
        Name = externalProduct.Name,
        Description = externalProduct.Description,
        AttributeValues = combination.Select(c => new AttributeValue
        {
            Attribute = c.Attribute,
            Value = c.Option
        }).ToList()
    })
    .ToList();

// 辅助方法:递归生成笛卡尔积
private static IEnumerable<IEnumerable<(string Attribute, string Option)>> GetCartesianProduct(List<dynamic> groups)
{
    if (groups.Count == 0)
    {
        yield return Enumerable.Empty<(string, string)>();
        yield break;
    }

    var firstGroup = groups[0];
    var remainingGroups = groups.Skip(1).ToList();

    foreach (var option in firstGroup.Options)
    {
        foreach (var combination in GetCartesianProduct(remainingGroups))
        {
            yield return new[] { (firstGroup.Attribute, option) }.Concat(combination);
        }
    }
}

代码说明

  1. 属性分组:将原始PayloadItem列表按Attribute归类,明确每个属性的可选值集合
  2. 笛卡尔积生成:通过递归方法遍历所有属性的可选值,生成包含所有属性的完整组合
  3. 变体映射:将每个属性组合转换为AttributeValue列表,同时复用外部产品的其他属性,得到最终的变体产品列表

示例输出(简化版)

[
    {
        "Name": "示例产品",
        "Description": "示例描述",
        "AttributeValues": [
            {"Attribute": "Size", "Value": "S"},
            {"Attribute": "Color", "Value": "Red"},
            {"Attribute": "Width", "Value": "100"},
            {"Attribute": "Length", "Value": "10000"}
        ]
    },
    {
        "Name": "示例产品",
        "Description": "示例描述",
        "AttributeValues": [
            {"Attribute": "Size", "Value": "S"},
            {"Attribute": "Color", "Value": "Red"},
            {"Attribute": "Width", "Value": "100"},
            {"Attribute": "Length", "Value": "20000"}
        ]
    },
    // ... 其余所有属性组合变体
]

内容的提问来源于stack exchange,提问作者Mead Alsorani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:44:56