如何将此linq转换为bool

时间:2019-01-06 22:59:53

标签: c# linq unity3d inventory

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

代码行

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

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

5 个答案:

答案 0 :(得分:3)

“库存中的所有项目都具有清单成本中显示的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中”

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

[更新]

您正在告诉我们以下内容:

  

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

     

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

     

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

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

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

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

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

答案 3 :(得分:0)

您可以使用Join创建基于方法的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);

答案 4 :(得分:0)

如果我正确理解,则listCost的元素可能比checkItemInventory 个。您要检查listCost中的所有元素在checkItemInventory中是否具有对应的元素。正确?如果是,请尝试以下操作:

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

我不知道这些列表的类型,因此您可能需要在某些地方使用x.id