-2

I'm trying to find an intersect on two collection where the items overlap having an inverse state.

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

Example:

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});

I would like to return samples from ListOfSamples2 that intersect with the samples that exist in ListOfSamples1 where the SampleState is opposite.

For instance ListOfSamples2[0] has a StartTime and EndTime that does reside in ListOfSamples1[0] and their states are opposite.

I am doing this with a ForEach but am looking for a more elegant way to do this that has more options.

Thank you

fuglede
  • 17,388
  • 2
  • 54
  • 99
7VNT
  • 41
  • 8
  • I am trying to understand the Linq intersect, after reading it seems that if I want to use Intersect I would need a comparer.I'm not that privy to Linq otherwise I would not be here. I attempted a IEqualityComparer public class SampleComparer2 : IEqualityComparer { public bool Equals(Sample xrSample, Sample islSample) { return xrSample.StateType != islSample.StateType; } public int GetHashCode(Sample sample) { return sample.GetHashCode(); } } – 7VNT Jun 10 '18 at 13:06
  • Does https://github.com/morelinq/MoreLINQ/issues/63 help? – mjwills Jun 10 '18 at 13:32
  • *Intersection* is a term from set theory. In relational algebra the same is called *join*. – Ivan Stoev Jun 10 '18 at 14:44
  • A set Intersect is not the same as a time period intersect, which I think is confusing here, since LINQ has an `Intersect` method. Perhaps if you said _overlapping_ it would be clearer? Also, then you could clarify if overlapping is sufficient or you need _containment_ of one time period by another? And can it happen in either direction? – NetMage Jun 12 '18 at 00:13
  • Thank you for the clarification and help with verbiage. Yes, I would say overlapping would suffice. – 7VNT Jun 13 '18 at 01:45

2 Answers2

0

If I understand the question correctly, you are trying to do what amounts to

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));
fuglede
  • 17,388
  • 2
  • 54
  • 99
0

as you mentioned you are trying to understand linq

here i have created a linq query to do what you want.

    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();

It will search for every entry in List2 (same as foreach(Sample sample in ListOfSamles2) ), if in List1 it find any entry (same as nested foreach loop) which satisfy all conditions, it will select that entry (sample) ofList2` and store it in resultant list.

same thing can be done like below too.

List<Sample> intersectSampleLamadaOnly = ListOfSamples2.Where(sample =>
       ListOfSamples1.Any(s => 
             s.StartTime < sample.StartTime && 
             s.EndTime > sample.EndTime && 
             s.SampleState != sample.SampleState)).ToList();
Amit
  • 1,821
  • 1
  • 17
  • 30