2015-02-23 17 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

相關問題