Как я могу конвертировать этот linq в bool - PullRequest
0 голосов
/ 07 января 2019

Как конвертировать запрос в bool? Я использовал «ВСЕ (x => x)», но не дал нужного мне ответа.

Кодовая строка

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

В этом случае listcost будет иметь 2 предметов, мне нужно было проверить, есть ли у checkItemInventory эти 2 предметов.

Ответы [ 5 ]

0 голосов
/ 07 января 2019

Если я правильно понял, listCost может иметь меньше элементов, чем checkItemInventory. Вы хотите проверить, что все элементы в listCost имеют соответствующий элемент в checkItemInventory. Правильный? Если да, попробуйте это:

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

Я не знаю тип этих списков, поэтому вам может понадобиться использовать x.id в некоторых местах

0 голосов
/ 07 января 2019

Вы можете использовать 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);
0 голосов
/ 07 января 2019

Вы можете сопоставить listCost со списком int, а затем использовать Except() и Any(), чтобы проверить, содержатся ли все элементы:

bool containsAll = !listCost.Select(x => x.Id).Except(checkItemInventory).Any();
0 голосов
/ 07 января 2019

[UPDATE]

Вы говорите нам следующее:

Как конвертировать запрос в bool? Я использовал «ВСЕ (x => x)», но не дал нужного мне ответа.

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

В этом случае список будет иметь 2 пункта, мне нужно было проверить, checkItemInventory содержит эти 2 элемента.

если вам нужно проверить, есть ли результат, вы можете использовать:

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

если вам нужно посчитать результат, вы можете использовать

 checkItemInventory.Where(x => listCost.Contains(x.Id)).Count();
0 голосов
/ 07 января 2019

"У всех предметов в инвентаре есть идентификатор, который присутствует в списке стоимости". listCost должен иметь то же количество предметов, что и инвентарь (при условии, что Id уникален), возможно, больше, чтобы иметь шанс вернуть true

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

"По крайней мере один предмет в инвентаре имеет идентификатор, который также находится в listCost". Listcost может иметь как минимум один идентификатор, чтобы иметь шанс вернуть 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(...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...