Петля внутри петли - PullRequest
       6

Петля внутри петли

2 голосов
/ 24 ноября 2010

Эй, ребята, я застрял в этой проблеме, и мне просто интересно, как лучше ее решить.

Foreach (var customer in CustomerList)
{
      Foreach (var appointment in AppointmentList)
      {
        if(appointment.customerId == customer.id)
           customer.appointments.add(appointment)


       }

}

это самый простой способ сделать это, но я не уверен, что он самый эффективный!

Любая помощь будет великолепна-

Спасибо.

Ответы [ 4 ]

2 голосов
/ 24 ноября 2010

Как насчет этого?

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

Для меня это выглядит как четкий и лаконичный синтаксис, и он объясняет, что он делает довольно хорошо.

Кроме того, я думаю, что здесь производительность должна быть хорошей и, вероятно, примерно такой же, как у исходного кода.

2 голосов
/ 24 ноября 2010

Вы могли бы возможно предварительно сгруппировать более короткий список; это должно дать вам лучшую производительность - я не могу найти цитаты с точными рейтингами big-O, поскольку MSDN их не цитирует, но может быть O (n + m) вместо O (n * m).

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

тогда вы можете использовать:

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

Или без LINQ (из комментариев):

// 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);
    }
}
0 голосов
/ 24 ноября 2010

Вы можете сделать свой customerList a Dictionary вместо состоящего из <id, cust>.

Затем, вместо того, чтобы зацикливать список, вы попытаетесь получить значение

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

Таким образом, вы позволяете Dictionary оптимизировать его для вас.
Обратите внимание, что если вы выполняете это действие только один раз, вероятно, не стоит много оптимизировать , если вы не заметите заметного замедления из него , Преждевременная оптимизация не стоит усилий

0 голосов
/ 24 ноября 2010

Вы можете использовать linq для удаления вложенности из циклов, например:

foreach (var customer in from customer in CustomerList
         from appointment in AppointmentList
         select customer)
{
    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...