【问题标题】:Linq code to get the index of an object in an array from an object within a listLinq 代码从列表中的对象获取数组中对象的索引
【发布时间】:2016-06-09 00:13:01
【问题描述】:

实际上,标题让我很困惑,我什至不确定它是否正确。我在这里遇到以下问题:我有一个列表,其中每个配方都包含一个 requiredItem[] 数组(大小 15) 这个必需的项目数组可以包含配方所需的项目。我想做的是将所有食谱放在一个单独的列表中,在他们的食谱中使用木材作为必需项目之一。 例如,一个配方可能需要 10 块木头来制作一张木桌。这个食谱在食谱列表中。快速的谷歌搜索让我找到了以下内容,但我不知道如何访问 requiredItem 索引:

 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);
        }

【问题讨论】:

  • 设置数据示例并向我们展示要返回的示例数据项。

标签: c# arrays linq filtering


【解决方案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() 函数。它选择所有包含指定类型成分的配方。

【讨论】:

  • 哇.. 编程时间太长的经典示例。这个清晰的例子使它变得如此简单。我能够使用以下代码实现我想要的。 numberRecipesRemoved += rec.RemoveAll(x => x.requiredItem.Any(i => i.type == ItemID.Wood && i.stack >= 10));这段代码现在完全符合我的要求,非常感谢:D(你的 GetAllRecipesUsingMaterial 示例也对我很有帮助)
【解决方案2】:

是的,这很简单,如果我理解您的问题,您需要出示所有包含木材的收据作为必填项。所以这样做:

var woodRecipes = recipes.Where(r => r.requiredItems.Contains(wood)).ToList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 2012-02-21
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多