从列表中选择

发布于 2024-10-30 17:21:06 字数 717 浏览 4 评论 0原文

我确信有一种简单的方法可以做到这一点(我猜是扩展方法之一?),但我很难通过 Google 找到它。

基本上我有一个自定义类列表;我想从中选择一些项目到一个新列表中,其中一个属性等于另一个列表中的任何值。

这是我想要做的一个(简化的)快速示例:

public class Job
    {
        public int Number;
        public string ClientCompanyName;            
    }

List<Job> lstJobs = new List<Job>();
List<Job> lstCompare = new List<Job>();

通常我会做类似的事情:

List<Job> lstFiltered = new List<Job>();
foreach(Job jobThis in lstCompare)
{
    foreach(jobComp in lstCompare)
    {
        if(jobThis.Number = jobComp.Number)
        {
            lstFiltered.Add(jobThis);
        }
    }
}

是否有一种扩展方法可以将最后一点整理成(理想情况下)单行?

干杯

I'm sure there's an wasy way of doing this (I'm guessing one of the extension methods?), but am struggling to find it with Google.

Basically I have a List of custom classes; I want to select some items from this into a new List where one of the properties is equal to any value in another List.

Here's a (simplified) quick example of what I'm trying to do:

public class Job
    {
        public int Number;
        public string ClientCompanyName;            
    }

List<Job> lstJobs = new List<Job>();
List<Job> lstCompare = new List<Job>();

normally I would do something like:

List<Job> lstFiltered = new List<Job>();
foreach(Job jobThis in lstCompare)
{
    foreach(jobComp in lstCompare)
    {
        if(jobThis.Number = jobComp.Number)
        {
            lstFiltered.Add(jobThis);
        }
    }
}

Is there an extension method that neatens this last bit up into (ideally) a single line?

Cheers

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

So尛奶瓶 2024-11-06 17:21:06

您可以使用 Intersect() 来实现此目的:

http://msdn.microsoft。 com/en-us/library/bb460136.aspx

忱杏 2024-11-06 17:21:06

使用相交 .
为了让它与您的自定义比较一起使用,您需要在您的类中实现 IEquatable 或创建一个新类,为您的类实现 IEqualityComparer 并传递这是 Intersect 的重载。

Use Intersect.
For it to work with your custom comparison you either need to implement IEquatable<T> in your class or create a new class the implements IEqualityComparer<T> for your class and pass that to the overload of Intersect.

往事随风而去 2024-11-06 17:21:06

天哪,

您也许可以使用 LINQ intersect 函数,或者尝试:

var matches = from jobs in lstJobs
               join comp in lstCompare on jobs.Number equals comp.Number
               select jobs;

或 LINQ 语法:

var matches = lstJobs.Join(lstCompare, jobs => jobs.Number,
                           comp => comp.Number, (jobs, comp) => jobs);

这是基于您原始循环的 reSharper 版本:

List<Job> lstFiltered = (lstJobs.SelectMany(jobThis => lstCompare, 
                        (jobThis, jobComp) => new {jobThis, jobComp})
                        .Where(@t => @t.jobThis.Number == @t.jobComp.Number)
                        .Select(@t => @t.jobThis)).ToList();

稍微冗长,但另一种剥皮的方法。

[编辑] 设置为新列表,而不是选定的元素 - doh

Jez,

You might be able to use the LINQ intersect function, or try:

var matches = from jobs in lstJobs
               join comp in lstCompare on jobs.Number equals comp.Number
               select jobs;

or LINQ syntax:

var matches = lstJobs.Join(lstCompare, jobs => jobs.Number,
                           comp => comp.Number, (jobs, comp) => jobs);

and here was reSharper's version based on your original loop:

List<Job> lstFiltered = (lstJobs.SelectMany(jobThis => lstCompare, 
                        (jobThis, jobComp) => new {jobThis, jobComp})
                        .Where(@t => @t.jobThis.Number == @t.jobComp.Number)
                        .Select(@t => @t.jobThis)).ToList();

slightly verbose, but another way to skin the cat.

[edited] as had set to new list, rather than selected elements - doh

朮生 2024-11-06 17:21:06
var lstFiltered = lstJobs
        .Where(job => lstCompare.Any(item => item.Number == job.Number))
        .ToList();

如果 lstCompare 中的项目数量较少,则上述解决方案效果很好。对于更大的比较列表,您可能需要使用一些基于哈希的集合。

var compareSet = new HashSet<int>(lstCompare.Select(item => item.Number));
var lstFiltered = lstJobs
        .Where(job => compareSet.Contains(job.Number))
        .ToList();

如果比较条件比较复杂或者多个地方需要比较条件,则应创建一个实现 IEqualityComparer 的比较器类。然后您可以使用 Intersect()方法,正如其他人已经建议的那样。然而,它在功能上与上述解决方案并不相同。它仅返回不同的元素,而我的解决方案返回所有匹配的元素。在某些应用中这可能是一个显着的差异。

如有必要,我的第二个示例可以轻松更改为使用 IEqualityComparerHashSet 将比较器作为第二个参数。

var lstFiltered = lstJobs
        .Where(job => lstCompare.Any(item => item.Number == job.Number))
        .ToList();

The above solution works well if the number of items in the lstCompare is small. For bigger comparison lists you may want to use some hash based collection.

var compareSet = new HashSet<int>(lstCompare.Select(item => item.Number));
var lstFiltered = lstJobs
        .Where(job => compareSet.Contains(job.Number))
        .ToList();

If the comparison condition is more complex or it is needed in several places, you should create a comparer class that implements IEqualityComparer<T>. Then you could use the Intersect() method as others have already suggested. However, it is not functionally identical with the above solutions. It returns only distinct elements while my solutions return all matching elements. It may be a significant difference in some applications.

My second example can be easily changed to use IEqualityComparer<T> if necessary. The HashSet<T> takes the comparer as second parameter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文