LINQ基于属性相交

时间:2018-06-10 12:30:42

标签: c# linq join intersect

我正在尝试在两个集合中找到一个交叉点,其中项目重叠具有反向状态。

public class Sample
{
    public int SampleNumber { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public bool SampleState { get; set; }
}

示例:

List<Sample> ListOfSamples1 = new List<Sample>();
List<Sample> ListOfSamples2 = new List<Sample>();

ListOfSamples1.Add( new Sample() {SampleNumber=1, StartTime = new DateTime(2018, 12, 1, 0, 0, 0), EndTime = new DateTime(2018, 12, 1, 0, 10, 0), SampleState= true });
ListOfSamples1.Add( new Sample() {SampleNumber=2, StartTime = new DateTime(2018, 12, 1, 0, 20, 0), EndTime = new DateTime(2018, 12, 1, 0, 30, 0), SampleState= false });

ListOfSamples2.Add( new Sample() {SampleNumber=3, StartTime = new DateTime(2018, 12, 1, 0, 5, 0), EndTime = new DateTime(2018, 12, 1, 0, 7, 0), SampleState= false});
ListOfSamples2.Add( new Sample() {SampleNumber=4, StartTime = new DateTime(2018, 12, 1, 0, 21, 0), EndTime = new DateTime(2018, 12, 1, 0, 22, 0), SampleState= true});

我想从ListOfSamples2返回与ListOfSamples1SampleState相对的样本相交的样本。

例如,ListOfSamples2[0]的{​​{1}}和StartTime位于EndTime,其状态相反。

我正在使用ListOfSamples1[0]执行此操作,但我正在寻找一种更优雅的方式来执行此操作,这有更多选项。

谢谢

2 个答案:

答案 0 :(得分:0)

如果我正确理解了这个问题,那么你正在努力做到

public static IEnumerable<Sample> MakeSamples(
    IEnumerable<Sample> listOfSamples1,
    IEnumerable<Sample> listOfSamples2) =>
    listOfSamples2.Where(s2 =>
        listOfSamples1.Any(s1 =>
            s1.SampleState != s2.SampleState &&
            s2.EndTime >= s1.StartTime &&
            s2.StartTime <= s1.EndTime));

答案 1 :(得分:0)

正如您所提到的,您正试图理解linq

在这里,我创建了一个linq查询来执行您想要的操作。

    List<Sample> intersectSample =
    (from sample in ListOfSamples2
        where
            ListOfSamples1.Any(s => s.StartTime < sample.StartTime &&
                                    s.EndTime > sample.EndTime &&
                                    s.SampleState != sample.SampleState)
        select sample).ToList();

它将搜索List2中的每个条目(与foreach(Sample sample in ListOfSamles2)相同),如果在List1中它找到满足所有条目的任何条目(与嵌套foreach循环相同)条件,它将选择该条目(sample) of List2`并将其存储在结果列表中。

同样的事情也可以像下面那样完成。

List<Sample> intersectSampleLamadaOnly = ListOfSamples2.Where(sample =>
       ListOfSamples1.Any(s => 
             s.StartTime < sample.StartTime && 
             s.EndTime > sample.EndTime && 
             s.SampleState != sample.SampleState)).ToList();