首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将此linq转换为bool

如何将此linq转换为bool
EN

Stack Overflow用户
提问于 2019-01-07 06:59:53
回答 3查看 729关注 0票数 -2

如何将查询转换为bool?我使用了"ALL (x => x)“,但是没有给出我需要的答案。

代码行

代码语言:javascript
复制
checkItemInventory.Where(x => listCost.Contains(x.Id));

在本例中,listcost将包含2项,我需要检查checkItemInventory是否包含这些2项。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-01-07 07:07:58

“清单中的所有项目都有一个id,该id存在于listcost中”。listCost需要与库存具有相同数量的项目(假设Id是唯一的),可能会更多,才有机会返回true

代码语言:javascript
复制
checkItemInventory.All(x => listCost.Contains(x.Id))

“清单中至少有一个项目的id也在listCost中”。Listcost最少只能有一个id,以便有机会返回true。

代码语言:javascript
复制
checkItemInventory.Any(x => listCost.Contains(x.Id))

正如您所看到的,这两个都不是您想要的,因为您似乎是在说,您想要检查listcost中的每一项是否也存在于库存中。这类似于最上面的代码,但反过来(“listCost中的所有项目都存在于inventory中”vs“所有inventory中的项目都存在于listcost中”

我想我会先从库存中做一个字典,除非它已经支持快速查找:

代码语言:javascript
复制
var d = checkItemInventory.Select(x => new { x.Id, x.Id }).ToDictionary();
var boolResult = listCost.All(lc => d.ContainsKey(lc));

如果库存很少,您可以使用此方法:

代码语言:javascript
复制
listCost.All(lc => checkItemInventory.Any(cii => cii.Id == lc));

请注意,在内部,它可能会执行以下操作:

代码语言:javascript
复制
bool all = true;
foreach(lc in listCost){
  bool found = false;
  foreach(cci in checkItemInventory)
    if(lc == cci.Id){
      found = true;
      break;
    }
  all &= found;
  if(!all)
    return false;
}
return true;

这是大量的重复比较(对于listCost中的每一项,都会扫描整个库存),可能会很慢

编辑

我要求澄清您如何存储您的库存和您的建设项目的成本。这是我的一个假设,以及基于它的解决方案是如何工作的:

假设你的清单中有物品的种类,并有一个计数来说明玩家携带了多少物品:

代码语言:javascript
复制
class InventoryItem{
  int ItemKindId { get; set;}
  int CountOf { get; set; }
}

player.Inventory.Add(new InventoryItem() { 
  ItemKindId = Constants.WOOD, //1
  CountOf = 10 //holding 10 items of wood
};
player.Inventory.Add(new InventoryItem() { 
  ItemKindId = Constants.STONE, //2
  CountOf = 5 //holding 5 items of stone
};

假设你有一个制作斧头的食谱,它需要1块木头和2块石头,但它按简单的顺序列出了它们:

代码语言:javascript
复制
int[] axeRecipe = new int[] { Constants.WOOD, Constants.STONE, Constants.STONE };

对食谱进行分组可能是最简单的:

代码语言:javascript
复制
var recipe = axeRecipe.GroupBy(item => item)

/*
  now we have a grouping of the recipe[item].Key as the material and a
  recipe[item].Count() of how much. The group is like a dictionary:

  recipe[Constants.WOOD] = new List<int>{ Constants.WOOD };
  recipe[Constants.STONE] = new List<int>{ Constants.STONE, Constants.STONE, };
  A group item has a Key and a list of objects that have that key
  Because my recipe was simply ints, the Key is the same number as all the 
  items in the list
*/

//for all items in the recipe
grp.All(groupItem =>
  //does the player inventory contain any item
  playerInventory.Any(inventoryItem => 
    //where the material kind is the same as the recipe key (material)
    inventoryItem.ItemKindId == groupItem.Key &&
    //and the count they have of it, is enough to make the recipe
    inventoryItem.CountOf >= groupItem.Count()
);

当然,如果您愿意,可以将其减少到一行:axeRecipe.GroupBy(...).All(...)

票数 3
EN

Stack Overflow用户

发布于 2019-01-07 07:29:51

您可以将listCost映射到int列表,然后使用Except()Any()检查是否包含所有项:

代码语言:javascript
复制
bool containsAll = !listCost.Select(x => x.Id).Except(checkItemInventory).Any();
票数 0
EN

Stack Overflow用户

发布于 2019-01-07 08:20:12

您可以使用Join创建基于方法的Linq查询,并使用结果检查列表的长度是否大于0。然后将其转换为布尔值。

代码语言:javascript
复制
var query = checkItemInventory.Join(listCost,
                                    inventory => inventory.Id,
                                    cost => cost.Id,
                                    (inventory, cost) => new { id = inventory.Id });

var count = query.ToList().Count();
var b = (count > 0);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54066690

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档