I started comparing lists for my little project. So far I can compare if the same items exists, or one value of this item fits the same value of another lists item. Atm Im comparing the names from two lists. I changed some code I found for my purpose.
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;
}
the function is called with:
Console.WriteLine("ListResInStock contains ListResNeeded: ===> " + ContainsResourceName(ListResNeeded, ListResInStock) + " <==="); // True
Console.WriteLine("ListResNeeded contains ListResInStock: ===> " + ContainsResourceName(ListResInStock, ListResNeeded) + " <==="); // False
Now I want to change it, so that it only returns true, if the name of the ressNeeded is there and the amount of ressInStock is >= the Amount of RessNeeded (for all resources of course).
Also If you could explain this part var list1WithName = ListResNeeded.Select(s => s.Name).ToList();
In detail to me would be nice because im not 100% sure what it does.
I really appreciate your help :-)
It's simply
private bool ContainsResourceName(IEnumerable<TestResources> ListResNeeded, IEnumerable<TestResources> ListResInStock)
{
return ListResNeeded.All(resNeeded =>
ListResInStock.Any(resInStock =>
resInStock.Name == resNeeded.Name &&
resInStock.Amount >= resNeeded.Amount
)
);
}
To understand the meaning of .Select
, .All
, .First
and many other functions of so called IEnumerable
interface, you'd have to learn about lazy evaluation in C#, and there's too much to say.
ListResNeeded.Select(s => s.Name).ToList();
and other operations with enumerators are easier to read from the end. So from the end: you make a list (of what?) of elements produced by Select
function (what does it produce?) it takes a resource s
and returns s.Name
of it (where are these resources coming from?) from the list ListResNeeded.
Again, you have to read more about IEnumerator
in C#, and about lazy evaluation in general. It's an inportant concept in programming.
PS And some warnings about the code you tried to use. What you do there:
var list1WithName = ListResNeeded.Select(s => s.Name).ToList();
var list2WithName = ListResInStock.Select(s => s.Name).ToList();
is making full copy of both arguments that were passed into the function (imagine these arrays would be much much bigger, what's the point of copying them?).
And there you make a new (third) list after traversing both of the previous completely, while what you actually look for is just a boolean answer.
result = !list1WithName.Except(list2WithName).Any();
You don't have to traverse both lists completely before you know that the answer is false. You just need to find a first resource that is missing and then stop the search (it's much much lighter)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.