2015-02-23 50 views
0

我努力为属性列表及其可能的值生成所有可能的组合。我想实现是这样的方法:为属性动态列表生成所有可能的组合及其值

public List<Variant> generateAllPossibleVariants(List<Attribute> attributes) 

属性类看起来如下:

public class Attribute { 
    public String Name { get; set; } 
    public ICollection<String> PossibleValues { get; protected set; } 
} 

所以,想象一下,你有2个属性的列表(在计数是动态的)与其可能的值:

attributeColor with possible Values of ("red", "blue") 
attributeSize with possible values of ("XL", "L") 

现在我的方法应该返回变的名单,而variant类看起来如下:

现在
public class Variant 
{ 
    public IDictionary<Attribute, string> AttributeValues { get; private set; } 
} 

我的方法应该返回类似下面的所有组合的列表:

List<Variant> : 
    Variant.AttributeValues { attributeColor => "red", attributeSize => "XL" } 
    Variant.AttributeValues { attributeColor => "red", attributeSize => "L" } 
    Variant.AttributeValues { attributeColor => "blue", attributeSize => "XL" } 
    Variant.AttributeValues { attributeColor => "blue", attributeSize => "L" } 
+0

这可能帮助:http://stackoverflow.com/questions/4073713/is-there-a-good-linq-way-do-a-cartesian-product – 2015-02-23 12:14:31

+0

我真的认为这就是为什么DB在哪里做的,如果你把数据存储在数据库中它会更清晰如何存储和拉动它。但这是我的看法。 – Liran 2015-02-23 12:29:27

回答

0

这不是一个优化的代码,但你可以得到的想法,并清理自己:

public void Main() 
{ 
    var attr1 = new MyAttribute { Name = "Colors", PossibleValues = new List<string> { "red", "blue" } }; 
    var attr2 = new MyAttribute { Name = "Sizes", PossibleValues = new List<string> { "XL", "L" } }; 
    var attr3 = new MyAttribute { Name = "Shapes", PossibleValues = new List<string> { "qube", "circle" } }; 
    var attrList = new List<MyAttribute> { attr1, attr2, attr3 }; 

    var result = attrList.Skip(1).Aggregate<MyAttribute, List<Variant>>(
     new List<Variant>(attrList[0].PossibleValues.Select(s => new Variant { AttributeValues = new Dictionary<MyAttribute, string> { {attrList[0], s} } })), 
     (acc, atr) => 
     { 
      var aggregateResult = new List<Variant>(); 

      foreach (var createdVariant in acc) 
      { 
       foreach (var possibleValue in atr.PossibleValues) 
       { 
        var newVariant = new Variant { AttributeValues = new Dictionary<MyAttribute, string>(createdVariant.AttributeValues) }; 
        newVariant.AttributeValues[atr] = possibleValue; 
        aggregateResult.Add(newVariant); 
       } 
      } 

      return aggregateResult; 
     }); 
} 

public class MyAttribute 
{ 
    public string Name { get; set; } 
    public ICollection<string> PossibleValues { get; set; } 
} 

public class Variant 
{ 
    public IDictionary<MyAttribute, string> AttributeValues { get; set; } 
} 
+0

这是伟大的。谢谢 – Marco 2015-02-23 14:10:25

0

您正在寻找cartesian product(动态尺寸)。

实现它的一个简单方法是对维度使用递归,并且每次对递归结果和其中一个维度调用笛卡尔积。

伪代码:

genAllPossibilities(list attributes) //each element in attributes is a list 
    if length(attributes) == 1: 
     return attributes[0] //the only element, which is a list of one attribute 
    else: 
     curr = head(attributes) // first element in the list 
     reminder = tails(attributes) // a list of all elements except the first 
     return cartesianProduct(genAllPossibilities(reminder), curr) 

cartesianProduct(list1, list2): 
    l = new list 
    for each x1 in list1: 
     for each x2 in list2: 
       l.append(new MyObject(x1,x2)) 
     return l 
+0

非常感谢你 – Marco 2015-02-23 14:09:50

相关问题