расширенный список сравнения в C# - PullRequest
2 голосов
/ 22 марта 2020

Я начал сравнивать списки для моего маленького проекта. До сих пор я могу сравнить, существуют ли одни и те же элементы, или одно значение этого элемента соответствует тому же значению другого элемента списков. Я сравниваю имена из двух списков. Я изменил некоторый код, который нашел для своих целей.

public class TestResources
{
     public string Name;
     public int Amount;

     public TestResources(string name, int amount)
     {
          Name = name;
          Amount = amount;
     }
}

TestResources[] ListResInStock = { new TestResources("wood", 1000), new TestResources("stone", 1000), new TestResources("sand", 1000), new TestResources("water", 1000) };
TestResources[] ListResNeeded = { new TestResources("wood", 800), new TestResources("stone", 800), new TestResources("sand", 375) };

private bool ContainsResourceName(IEnumerable<TestResources> ListResNeeded, IEnumerable<TestResources> ListResInStock)
{
     bool result;

     var list1WithName = ListResNeeded.Select(s => s.Name).ToList();
     var list2WithName = ListResInStock.Select(s => s.Name).ToList();

     result = !list1WithName.Except(list2WithName).Any();

     return result;
}

функция вызывается с помощью:

Console.WriteLine("ListResInStock contains ListResNeeded:   ===> " + ContainsResourceName(ListResNeeded, ListResInStock) + " <===");    // True
Console.WriteLine("ListResNeeded contains ListResInStock:   ===> " + ContainsResourceName(ListResInStock, ListResNeeded) + " <===");    // False

Теперь я хочу изменить его, чтобы он возвращал значение true, только если имя ressNeeded есть, а количество ressInStock>> = количество RessNeeded (для всех ресурсов, конечно).

Также Если бы вы могли объяснить эту часть var list1WithName = ListResNeeded.Select(s => s.Name).ToList(); Подробно для меня было бы неплохо, потому что Я не уверен на 100%, что он делает.

Я очень ценю вашу помощь: -)

1 Ответ

3 голосов
/ 22 марта 2020

Это просто

private bool ContainsResourceName(IEnumerable<TestResources> ListResNeeded, IEnumerable<TestResources> ListResInStock)
{
     return ListResNeeded.All(resNeeded => 
         ListResInStock.Any(resInStock => 
              resInStock.Name == resNeeded.Name && 
              resInStock.Amount >= resNeeded.Amount
         )
     );
}

Чтобы понять значение .Select, .All, .First и многих других функций так называемого интерфейса IEnumerable, вам придется изучить ленивый вычисление в C#, и есть слишком много, чтобы сказать.

ListResNeeded.Select(s => s.Name).ToList(); и другие операции с перечислителями легче читать с конца. Итак, с конца: вы составляете список (что?) Элементов, созданных функцией Select (что она производит?), Она берет ресурс s и возвращает s.Name его (откуда эти ресурсы поступают ?) из списка ListResNeeded.

Опять же, вы должны прочитать больше о IEnumerator в C# и о ленивой оценке в целом. Это важное понятие в программировании.

PS И некоторые предупреждения о коде, который вы пытались использовать. Что вы там делаете:

var list1WithName = ListResNeeded.Select(s => s.Name).ToList();
var list2WithName = ListResInStock.Select(s => s.Name).ToList();

делает полную копию обоих аргументов, переданных в функцию (представьте, что эти массивы будут намного больше, какой смысл их копировать?).

И вы создаете новый (третий) список после полного обхода обоих предыдущих, тогда как на самом деле вы ищете просто логический ответ.

result = !list1WithName.Except(list2WithName).Any();

Вы не Вам нужно полностью пройти оба списка, прежде чем вы узнаете, что ответ ложный. Вам просто нужно найти первый ресурс, который отсутствует, а затем прекратить поиск (он намного легче)

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