开发者

Loop within a Loop

开发者 https://www.devze.com 2023-01-27 05:38 出处:网络
Hey guys - I\'m stuck with this problem and im just wondering what the best way to handle it is. Foreach (var customer in开发者_JS百科 CustomerList)

Hey guys - I'm stuck with this problem and im just wondering what the best way to handle it is.

Foreach (var customer in开发者_JS百科 CustomerList)
{
      Foreach (var appointment in AppointmentList)
      {
        if(appointment.customerId == customer.id)
           customer.appointments.add(appointment)


       }

}

this is the simplest way I can think to do it but im not sure if it's the most efficient!

Any help would be great-

Thanks.


You could perhaps pre-group the shorter list; this should give you better performance - I can't find citations to the exact big-O ratings since MSDN doesn't cite them, but it could be O(n + m) instead of O(n * m).

var apptsByCustomer = AppointmentList.ToLookup(appt => appt.customerId);

then you can use:

foreach (var customer in CustomerList) {
    foreach(var appointment in apptsByCustomer[customer.id]) {
        customer.appointments.add(appointment);
    }
}

Or without LINQ (from comments):

// this bit is **broadly** comparable to ToLookup...
Dictionary<int, List<Appointment>> apptsByCustomer =
     new Dictionary<int, List<Appointment>>();
List<Appointment> byCust;
foreach(Appointment appt in AppointmentList) {            
    if (!apptsByCustomer.TryGetValue(appt.customerId, out byCust)) {
        byCust = new List<Appointment>();
        apptsByCustomer.Add(appt.customerId, byCust);
    }
    byCust.Add(appt);
}

foreach (Customer cust in CustomerList) {
    if (apptsByCustomer.TryGetValue(cust.id, out byCust)) {
        foreach (Appointment appt in byCust) cust.appointments.Add(appt);
    }
}


What about this?

foreach (var customer in CustomerList)
{
    customer.AddRange( appointment.Where( a => a.CustomerId == customer.id));
}

For me this seems like a clear and concise syntax, and it explains what it does quite good.

Also, I think the performance should be fine here, and probably around the same as your original code.


You could use linq to remove nesting from loops, like this:

foreach (var customer in from customer in CustomerList
         from appointment in AppointmentList
         select customer)
{
    // ...
}


You could make your customerList a Dictionary instead consisting of <id, cust>.

Then, instead of looping the list you try to get the value

Dictionary<int, Customer> customerList = new Dictionary<int, Customer>();
// populate your list
// ...
foreach (var appointment in AppointmentList)
{
    Customer customer;
    if (customerList.TryGetValue(appointment.customerID, out customer)){
        // found the customer
        customer.appointments.add(appointment)
}

This way, you let Dictionary optimize it for you.
Do note that if you only perform this action once, it's probably not worth optimizing much unless you see a notable slowdown from it. Premature optimization is not really worth the effort

0

精彩评论

暂无评论...
验证码 换一张
取 消