Mr. Monster
Mr. Monster

Reputation: 31

Is there any efficient way to optimize following Linq

private static List<Patient> GetPatientData()
{
    return  new List<Patient>()
    {
        new Patient(1,new List<Case>() { new Case(10, CaseType.ambulant)}),
        new Patient(2,new List<Case>() { new Case(20, CaseType.ambulant), new Case(21, CaseType.ambulant), new Case(22, CaseType.stationaer),new Case(23, CaseType.teilstat) }),
        new Patient(3,new List<Case>() { new Case(30, CaseType.ambulant), new Case(31, CaseType.ambulant), new Case(32, CaseType.stationaer), new Case(33, CaseType.stationaer), new Case(34, CaseType.teilstat) }),
        new Patient(4,new List<Case>() { new Case(40, CaseType.ambulant), new Case(41, CaseType.stationaer), new Case(43, CaseType.teilstat), new Case(44, CaseType.ambulant), new Case(45, CaseType.stationaer), new Case(46, CaseType.teilstat) }),
        new Patient(5,new List<Case>() {new Case(53, CaseType.teilstat),new Case(54, CaseType.teilstat) })
    };                                 
}

List<Patient> patientList = GetPatientData();
var result = patientList.SelectMany(item => item.CaseList.Select(itemCase=> itemCase.CaseType).Distinct());            
foreach (CaseType item in result)
{
    Console.WriteLine("CaseTypes = {0}",item);                
}

The above code gives the list of Patient, from that I want a distinct case list. So is there any optimized way to do this from what I have done?

    Dictionary<int, int> result = patientList.ToDictionary(item => item.PatientID , item=> item.CaseList.Select(x=>x.CaseType).Distinct().Count());            
    foreach (KeyValuePair<int,int> item in result)
    {
        Console.WriteLine("{0} {1}", item.Key,item.Value);
    }

In Second case i am trying to get patientID & Distinct CaseType Count for that particular patient. can i optimize this one.

Upvotes: 1

Views: 117

Answers (2)

primfaktor
primfaktor

Reputation: 2997

To get the distinct case types of all patients in that list, I used

var result =
    (
    from patient in patientList
    from typ in patient.CaseList
    select typ.CaseType
    ).Distinct();

foreach (var item in result)
{
    Console.WriteLine("CaseTypes = {0}", item);
}

Of course, you could rewrite it method-style.

To get the same distinct case list, but per patient, try this:

var result =
    (
    from patient in patientList
    group patient by patient.PatientID into g
    from patient in g
    from typ in patient.CaseList
    select new { ID = g.Key, Type = typ.CaseType }
    ).Distinct();

foreach (var item in result)
{
    Console.WriteLine("Patient {0} has the following case: {1}", item.ID, item.Type);
}

An alternative (less repeating) way to present the results is to group:

var result =
    (
        from patient in patientList
        group patient by patient.PatientID into g
        from p in g
        select new { g.Key, List = p.CaseList.Select(c => c.CaseType).Distinct() }
    ).ToDictionary(kv => kv.Key, kv => kv.List);

foreach (var item in result)
{
    Console.WriteLine("Patient {0} has the following cases:", item.Key);
    foreach (var type in item.Value)
    {
        Console.WriteLine("\t{0}", type);
    }
}

Upvotes: 1

Bruno Garcia
Bruno Garcia

Reputation: 6408

You are missing a last Distinct:

var result = patientList.SelectMany(item => item.CaseList.Select(itemCase => itemCase.CaseType).Distinct()).Distinct();

There's nothing to improve there.

You could choose to keep only the last Distinct (so there's one less Enumerator to be created) but having it gives you less results yielded out to your final Distinct. Performance then would change depending on the amount of data (number of Patients and Cases per Patient) though nothing that would make any difference.

Upvotes: 1

Related Questions