为了账号安全,请及时绑定邮箱和手机立即绑定

如何将此 linq 转换为 bool

如何将此 linq 转换为 bool

C#
隔江千里 2022-07-10 16:02:35
如何将查询转换为布尔值?我使用了“ALL (x => x)”,但没有给出我需要的答案。代码行checkItemInventory.Where(x => listCost.Contains(x.Id));在这种情况下,listcost将有2项目,我需要检查是否checkItemInventory有这些2项目。
查看完整描述

4 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

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


checkItemInventory.All(x => listCost.Contains(x.Id))

“库存中至少有一件物品的 id 也在 listCost 中”。Listcost 至少可以只有一个 id,才有机会返回 true


checkItemInventory.Any(x => listCost.Contains(x.Id))

如您所见,这些都不是您想要的,因为您似乎在说您想检查 listcost 中的每个项目是否也存在于库存中。这就像顶部代码,但反过来(“listCost 中的所有项目都存在于库存中”与“库存中的所有项目都存在于 listcost 中”


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


var d = checkItemInventory.Select(x => new { x.Id, x.Id }).ToDictionary();

var boolResult = listCost.All(lc => d.ContainsKey(lc));

如果库存很小,您可以使用这种方法:


listCost.All(lc => checkItemInventory.Any(cii => cii.Id == lc));

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


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 中的每个项目,都会扫描整个库存),可能会很慢


编辑

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


假设您的库存中有物品的种类和计数,说明玩家携带了多少物品:


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 个石头,但它以简单的顺序列出它们:


int[] axeRecipe = new int[] { Constants.WOOD, Constants.STONE, Constants.STONE };

可能最容易对配方进行分组:


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(...)


查看完整回答
反对 回复 2022-07-10
?
撒科打诨

TA贡献1934条经验 获得超2个赞

您告诉我们以下内容:

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

checkItemInventory.Where(x => listCost.Contains(x.Id));

在这种情况下,listcost 将有 2 个项目,我需要检查 checkItemInventory 是否有这 2 个项目。

如果您需要检查是否有任何结果,那么您可以使用:

bool hasItems = checkItemInventory.Where(x => listCost.Contains(x.Id)).Any();

如果您需要计算结果,您可以使用

 checkItemInventory.Where(x => listCost.Contains(x.Id)).Count();


查看完整回答
反对 回复 2022-07-10
?
www说

TA贡献1775条经验 获得超8个赞

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


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


查看完整回答
反对 回复 2022-07-10
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

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

bool containsAll = !listCost.Select(x => x.Id).Except(checkItemInventory).Any();


查看完整回答
反对 回复 2022-07-10
  • 4 回答
  • 0 关注
  • 165 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号