Search code examples
c#linqusertype

Find common items in list of lists of user type


I have a studyTimeList that contains lists of ScheduleStudyTime - my user type. I'm trying to find a common ScheduleStudyTime among the lists. Here is my code:

    private class ScheduleStudyTime
    {
        public int STUDTIME_ID { get; set; }

        public int DAY_ID { get; set; }

        public int LESSTIME_ID { get; set; }

        public int SCHOOLYEAR_ID { get; set; }
    }

    private void LoadStudyTime()
    {
        var fourths = dbContext.FOURTH.Where(x => x.CHOOSE_SCHEDULE_FOURTH.Any(a => a.SCHEDVARIANT_ID == ScheduleVariant.SCHEDVARIANT_ID)).ToList();
        int fourthCount = fourths != null ? fourths.Count() : 0;
        List<ScheduleStudyTime>[] studyTimeList = new List<ScheduleStudyTime>[fourthCount];
        for (int i = 0; i <= (fourthCount - 1); ++i)
        {
            int fourthId = fourths[i].FOURTH_ID;
            var chooseStudyTime = from CHOOSE_STUDY_FOURTH in dbContext.CHOOSE_STUDY_FOURTH
                                  where CHOOSE_STUDY_FOURTH.STUDY_TIME.SCHOOLYEAR_ID == Properties.Settings.Default.SchoolYearId &&
                                  CHOOSE_STUDY_FOURTH.FOURTH_ID == fourthId
                                  group CHOOSE_STUDY_FOURTH by new
                                  {
                                      CHOOSE_STUDY_FOURTH.STUDY_TIME.STUDTIME_ID,
                                      CHOOSE_STUDY_FOURTH.STUDY_TIME.DAY_ID,
                                      CHOOSE_STUDY_FOURTH.STUDY_TIME.LESSTIME_ID,
                                      CHOOSE_STUDY_FOURTH.STUDY_TIME.SCHOOLYEAR_ID
                                  }
                                  into gcsf
                                  select new ScheduleStudyTime
                                  {
                                      STUDTIME_ID = gcsf.Key.STUDTIME_ID,
                                      DAY_ID = gcsf.Key.DAY_ID,
                                      LESSTIME_ID = gcsf.Key.LESSTIME_ID,
                                      SCHOOLYEAR_ID = gcsf.Key.SCHOOLYEAR_ID
                                  };
            studyTimeList[i] = chooseStudyTime.ToList();
        }
        var commonStudyTime = studyTimeList.Aggregate((xs, ys) => xs.Intersect(ys).ToList());
    }

How can I do this if commonStudyTime returns zero, even if there are matches


Solution

  • The Intersect method will use the default comparer which basically checks (for reference types) if the references are the same. Since your list has object types, and they are different objects, it returns 0 results.

    To do what you want, you have to tell the Intersect method how to do the comparison check. So you need something like:

    public class ScheduleStudyTimeComparer : IEqualityComparer<ScheduleStudyTime>
    {
        public bool Equals(ScheduleStudyTime x, ScheduleStudyTime y)
        {
            // TODO: Check for nulls and possibly make the decision using
            // other properties as well
            return x.STUDTIME_ID  == y.STUDTIME_ID ;
        }
    
        public int GetHashCode(ScheduleStudyTime obj)
        {
            return obj.ScheduleStudyTime.GetHashCode();
        }
    }
    

    Now tell the Intersect method to use that:

    xs.Intersect(ys, new ScheduleStudyTimeComparer())