简体   繁体   English

C#中的高级列表比较

[英]advanced list comparison in C#

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. Atm Im 比较来自两个列表的名称。 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).现在我想更改它,以便它仅返回 true,如果 ressNeeded 的名称存在并且 ressInStock 的数量 >= RessNeeded 的数量(当然对于所有资源)。

Also If you could explain this part var list1WithName = ListResNeeded.Select(s => s.Name).ToList();另外如果你能解释这部分var list1WithName = ListResNeeded.Select(s => s.Name).ToList(); In detail to me would be nice because im not 100% sure what it does.详细对我来说会很好,因为我不能 100% 确定它的作用。

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.要理解.Select.All.First以及所谓的IEnumerable接口的许多其他函数的含义,您必须了解 C# 中的惰性求值,而且要说的太多了。

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.因此,从结尾:你犯了一个列表(是什么?)由生产要素的Select功能(这是什么生产?)它需要一个资源s ,并返回s.Name从它(其中在这些资源来自哪里?)列出 ListResNeeded。

Again, you have to read more about IEnumerator in C#, and about lazy evaluation in general.同样,您必须阅读有关 C# 中的IEnumerator更多信息,以及一般的惰性求值。 It's an inportant concept in programming.这是编程中的一个重要概念。

PS And some warnings about the code you tried to use. PS 还有一些关于您尝试使用的代码的警告。 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)你只需要找到第一个丢失的资源然后停止搜索(它要轻得多)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM