查找一个项目的可能变化

问题描述:

在我的申请中,我有食谱的概念,每个食谱都有可以被另一种成分替代的成分。我想要做的是产生每种成分的可能性。我有以下结构CLR对象:查找一个项目的可能变化

public class Food 
{ 
    public Food() 
    { 
     NutritionalValues = new Collection<FoodNutritionalValue>(); 
    } 

    public string Name { get; set; } 
    public string Category { get; set; } 

    public ICollection<FoodNutritionalValue> NutritionalValues { get; set; } 
} 

public class FoodNutritionalValue 
{ 
    public string Type { get; set; } 
    public decimal Value { get; set; } 
} 

public class Recipe 
{ 
    public Recipe() 
    { 
     IngredientGroups = new Collection<IngredientGroup>(); 
    } 

    public string Name { get; set; } 
    public ICollection<IngredientGroup> IngredientGroups { get; set; } 
} 

public class IngredientGroup 
{ 
    public IngredientGroup() 
    { 
     Ingredients = new Collection<Food>(); 
    } 

    public ICollection<Food> Ingredients { get; set; } 
} 

IngredientGroup的东西,可以相互替代。因此,对于配方而言,每个Ingredients组需要一种配料。然而,因为我不知道IngredientGroups的数量,我无法遍历它们以找出每种可能性。

例如,如果我知道IngredientGroups.Count的事先

Recipe recipe2 = new Recipe(); 
IngredientGroup ingredientGroup3 = new IngredientGroup(); 
IngredientGroup ingredientGroup4 = new IngredientGroup(); 
IngredientGroup ingredientGroup5 = new IngredientGroup(); 

recipe2.Name = "Recipe2"; 
ingredientGroup3.Ingredients.Add(new Food { Name = "Food8", Category = "Categor8" }); 
ingredientGroup3.Ingredients.Add(new Food { Name = "Food9", Category = "Categor9" }); 

ingredientGroup4.Ingredients.Add(new Food { Name = "Food5", Category = "Categor5" }); 
ingredientGroup4.Ingredients.Add(new Food { Name = "Food10", Category = "Categor10" }); 
ingredientGroup4.Ingredients.Add(new Food { Name = "Food11", Category = "Category11" }); 

ingredientGroup5.Ingredients.Add(new Food { Name = "Food3", Category = "Categor3" }); 
ingredientGroup5.Ingredients.Add(new Food { Name = "Food4", Category = "Categor4" }); 

recipe2.IngredientGroups.Add(ingredientGroup3); 
recipe2.IngredientGroups.Add(ingredientGroup4); 
recipe2.IngredientGroups.Add(ingredientGroup5); 

var recipes = new[] { recipe2 }; 

List<string> results = new List<string>(); 
foreach (var rcp in recipes) 
{ 
    var group1 = rcp.IngredientGroups.ElementAt(0); 
    var group2 = rcp.IngredientGroups.ElementAt(1); 
    var group3 = rcp.IngredientGroups.ElementAt(2); 

    foreach (var item1 in group1.Ingredients) 
     foreach (var item2 in group2.Ingredients) 
      foreach (var item3 in group3.Ingredients) 
      { 
       results.Add(string.Format("{0}, {1}, {2}", item1.Name, item2.Name, item3.Name)); 
      } 
} 

计数我敢肯定,我失去了一些东西太大,这里将下面的代码工作正常。任何人都知道如何在运行时产生所有可能性?

基于发现Here的答案,你很可能使用相同的辅助方法:

public static List<List<T>> CombinationsOf<T>(List<List<T>> sets) 
{  
    var combinations = new List<List<T>>(); 

    foreach (var value in sets[0]) 
    combinations.Add(new List<T> { value }); 

    foreach (var set in sets.Skip(1)) 
    combinations = AddSet(combinations, set); 

    return combinations; 
} 

private static List<List<T>> AddSet<T>(List<List<T>> combinations, List<T> set) 
{ 
    var result = from value in set 
       from combination in combinations 
       select new List<T>(combination) { value }; 

    return result.ToList(); 
} 

用法示例(基于OP的例子)

... 
var foods = recipes.SelectMany(recipe => 
    recipe.IngredientGroups.Select(ingredient => 
    ingredient.Ingredients.Select(o => o.Name).ToList())); 

var results = from combination in CombinationsOf(foods.ToList()) 
       select string.Join(", ", combination); 
... 

输出

results := 

Food8, Food5, Food3 
Food9, Food5, Food3 
Food8, Food10, Food3 
Food9, Food10, Food3 
Food8, Food11, Food3 
Food9, Food11, Food3 
Food8, Food5, Food4 
Food9, Food5, Food4 
Food8, Food10, Food4 
Food9, Food10, Food4 
Food8, Food11, Food4 
Food9, Food11, Food4