繁体   English   中英

LINQ 查询比较两个列表与子列表

[英]LINQ Query comparing two lists with sublist

我正在制作一个具有制作系统的游戏。 我正在尝试获取食谱列表,但只显示玩家在他们的库存中拥有足够多的食谱。 我很难弄清楚这个查询。 这是我的精简课程:

public class GameItem
{
    public string itemName;
    public int quantityHeld;
}

public class GameItemRecipe : GameItem
{
    public GameItemIngredient[] giiIngredients;
}

public class GameItemIngredient : GameItem
{        
    public int quantityNeeded;
}

所以我有一个 GameItems 列表; 那是玩家的物品栏。 然后我有一个玩家知道的食谱的单独列表。 食谱有一个制作它所需成分的子列表。 所以我想获取库存中有足够物品的食谱列表。 任何帮助表示赞赏。

var recipes = new List<GameItemRecipe>();
var inventory = new List<GameItem>();

var possibleRecipes = recipes.Where(rec => r.giiIngredients.
                          All(i => ing.quantityNeeded <= inventory.
                          FirstOrDefault(gi => gi.itemName== ing.itemName)?.quantityHeld));

此查询获取您的所有食谱,其中对于所有成分,数量需求字段小于或等于游戏物品清单中具有相同物品名称的游戏物品的持有数量字段。

所以你有一个Player ,这个 Player 有一个Inventory ,它是一系列GameItems 其中一些 GameItems 可能是GameItemIngredients 您没有指定 Inventory 中的所有 GameItems 都是 GameItemIngredients,因此 Inventory 中的某些 GameItems 可能不是 GameItemIngredients。

此外,玩家知道GameItemRecipes的序列。 要制作其中一种配方,玩家需要配方中提到的GameItemIngredients

玩家需要知道他可以制作哪些食谱。 换句话说:对于哪些食谱,玩家有足够的成分。

IEnumerable<GameItem> inventory = ...
IEnumerable<GameItemRecipe> recipes = ...

从中您可以提取玩家在他的库存中拥有的所有成分:

IEnumerable<GameItemIngredient> ingredients = inventory.OfType<GameItemRecipe>();

要求:给我玩家可以制作的所有食谱; 这些都是玩家拥有所有成分的食谱。

每个 GameItemIngredient 都有一个属性RequiredQuantity 我假设每个食谱都会有制作食谱所需的 GameItemIngredients 的唯一名称。

简单地说:如果你需要两个土豆来制作食谱“土豆泥”,那么食谱的成分列表将只包含一种名称为“土豆”的成分。 该成分的数量为 2。因此,您的食谱中不会出现两次土豆成分。

此外,我假设您不会在食谱中进行子分类:如果您的食谱需要“苹果”,并且您的库存中有“史密斯奶奶”,那么唉,您无法制作食谱,甚至虽然“Granny Smith”是“Apple”。

如果配方的所有成分都在库存的成分中并且QuantityNeeded <= QuantityHeld ,则可以制作配方。

因此,对于每个配方,我们都需要检查成分是否在库存中。 为了提高效率,我们将制作库存中成分的字典。 Key是成分的ItemName 值是QuantityHeld

var ingredientQuantities = ingredients.ToDictionary(
    ingredient => ingredient.ItemName,
    ingredient => ingredient.QuantityHeld);

如果“Apple”与“apple”的成分相同,请考虑使用 EqualityComparer

配方中每种成分的 ItemName 应该是 Dictionary 中的一个键,并且 QuantityNeeded <= QuantityHeld (= Dictionary 中的值)

var recipesThatCanBeMade = recipes
   .Where(recipe => !recipe.Ingredients.All(ingredient =>
       ingredientQuantities.TryGetValue(ingredient.ItemName, out int quantityHeld)
       && ingredient.QuantityNeeded <= quantityHeld)

换句话说:从食谱序列中的每个食谱中,只保留那些食谱

  • 所有成分都有一个 ItemName ,它是字典中的一个键,
  • 并且有一个 QuantityNeeded,它小于或等于 Dictionary 中对应值的 QuantityHeld。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM