2016-06-09 51 views
2

实际上,标题让我感到困惑,我甚至不确定它是否正确。我在这里有以下问题:我有一个列表,其中每个配方持有一个requiredItem []数组(大小15)此必需的项目数组可以容纳配方所需的项目。我想要做的是将所有食谱放在一个单独的列表中,在他们的食谱中使用木材作为必需项目之一。例如,一个配方可能需要10块木头来制作一张木桌。此配方在配方列表中。快速谷歌搜索让我找到下面,但我想不通我怎么能访问requiredItem指标:从一个列表中的对象获取数组中对象索引的Linq代码

List<Recipe> rec = Main.recipe.ToList(); 
rec.Select((s, i) => new { i, s }) 
.Where(t => t.s.requiredItem[indexhere].type == 9) 
.Select(t => t.i) 
.ToList() 

我很抱歉,我没有看到这一点,我也不会感到惊讶,如果答案很简单。

另外我试了下面。它不会带来任何错误,但实际上并未选择食谱。

 Item refItem = new Item(); 
     refItem.SetDefaults(ItemID.Wood, false); 
     List<int> selectWood = new List<int>(rec.Select((r, i) => new { i, r }).Where(x => x.r.requiredItem.ToList().Contains(refItem)).Select(x => x.i).ToList()); 
     ErrorLogger.Log(selectWood.ToArray().ToString()); 
     List<int> indices = new List<int>(); 
     foreach (var indice in selectWood) 
     { 
      for (int i = 0; i < Main.recipe[indice].requiredItem.Length; i++) 
      { 
       var item = Main.recipe[indice].requiredItem[i]; 
       if (item.type == ItemID.Wood && item.stack >= 10) indices.Insert(0, indice); 
      } 
     } 

     foreach (var indice in indices) 
     { 
      ++numberRecipesRemoved; 
      rec.RemoveAt(indice); 
     } 
+0

设置数据示例并向我们显示要返回的示例数据项。 – OmegaMan

回答

1

我可能读错的问题,但为什么你需要和索引(indexHere)作为Any()条款应该足够了它不是完全明显。

没有关于ReciperequiredItem的详细信息,很难确定,但以下内容似乎可以实现您所需的功能。

enum MaterialType 
{ 
    None, 
    Wood, 
    Glass, 
    Steel, 
    Cloth 
} 

class Ingredient 
{ 

    public Ingredient(MaterialType type, int amount) 
    { 
     Type = type; 
     Amount = amount; 
    } 

    public MaterialType Type { get; } 
    public int Amount { get; } 
} 

class Recipe 
{ 

    public Recipe(string name, params Ingredient[] ingredients) 
     : this(name, (IEnumerable<Ingredient>) ingredients) 
    {   
    } 

    public Recipe(string name, IEnumerable<Ingredient> ingredients) 
    { 
     Name = name; 
     Ingredients = ingredients.ToArray(); 
    } 

    public string Name { get; } 
    public Ingredient[] Ingredients { get; } 
} 

[TestClass] 
public class FindAllItemsFixture 
{ 

    private readonly static IEnumerable<Recipe> AllItemRecipes = new List<Recipe> 
    { 
     new Recipe("Sword", new Ingredient(MaterialType.Steel, 3)), 
     new Recipe("Spear", new Ingredient(MaterialType.Steel, 1), new Ingredient(MaterialType.Wood, 3)), 
     new Recipe("Table", new Ingredient(MaterialType.Wood, 6)), 
     new Recipe("Chair", new Ingredient(MaterialType.Wood, 4)), 
     new Recipe("Flag", new Ingredient(MaterialType.Cloth, 2)), 

    }; 

    IEnumerable<Recipe> GetAllRecipesUsingMaterial(MaterialType materialType) 
    { 
     return AllItemRecipes.Where(r => r.Ingredients.Any(i => i.Type == materialType)); 
    } 


    [TestMethod] 
    public void GetAllWoodenRecipes() 
    { 
     var expectedNames = new string[] { "Spear", "Table", "Chair" }; 
     var woodenItems = GetAllRecipesUsingMaterial(MaterialType.Wood); 
     CollectionAssert.AreEqual(expectedNames, woodenItems.Select(i => i.Name).ToArray()); 

    } 

    [TestMethod] 
    public void GetAllClothRecipes() 
    { 
     var expectedNames = new string[] { "Flag" }; 
     var clothItems = GetAllRecipesUsingMaterial(MaterialType.Cloth); 
     CollectionAssert.AreEqual(expectedNames, clothItems.Select(i => i.Name).ToArray()); 

    } 
} 

重要的是单元测试中的GetAllRecipesUsingMaterial()函数。它选择所有包含指定类型成分的配方。

+0

Woow ..编程的经典例子太长了。这个清晰的例子使它变得如此简单。我能用下面的代码实现我想要的。 numberRecipesRemoved + = rec.RemoveAll(x => x.requiredItem.Any(i => i.type == ItemID.Wood && i.stack> = 10)); 这段代码现在正在做我想要的东西,非常感谢你:D(也是你的GetAllRecipesUsingMaterial例子真的帮助我) – Jofairden

1

是的,这很简单,如果我理解你的问题,你需要显示包含木材所有需要的项目的recepies。因此,请这样做:

var woodRecipes = recipes.Where(r => r.requiredItems.Contains(wood)).ToList(); 
相关问题