Dart - GroupBy с вложенными списками - PullRequest
0 голосов
/ 27 мая 2020

Можно использовать героя Дротика. Совершенно новый, поэтому позвольте мне попытаться объяснить коротко, но правильно

У меня следующая структура объекта

  • Клиент имеет List<Project>

  • Проект имеет List<Registration>

  • Регистрация имеет дату в поле типа DateTime

class Client {

  String id;
  String name;
  String hexColor;
  List<Project> projects;

}

class Project {

  String id;
  String name;
  List<Registration> registrations;

}

class Registration {

  String id;
  String description;
  DateTime date;
  int minutesWorked;

}

Итак, в настоящее время у меня есть a List<Client>, но я хочу сделать GroupBy на основе значения Registration.date ... как сделать groupBy с вложенным списком?

Ожидаемый результат:

[
  2020-01-01 00:00:00.000: [Instance of Client, Instance of Client, Instance of Client], 
  2020-01-02 00:00:00.000: [Instance of Client]
]

как, черт возьми, это должно быть сделано!

1 Ответ

1 голос
/ 27 мая 2020

Как насчет:

Map<DateTime, List<Client>> clientsByRegsitrationDate(Iterable<Client> clients) {
  var result = <DateTime, List<Client>>{};
  for (var client in clients) {
    for (var registration in client.registrations) {
      result.putIfAbsent(registration.date, () => []).add(client);
    }
  }
  return result;
}

Это предполагает, что все даты регистрации для одного и того же клиента разные, иначе один и тот же клиент может оказаться в списке более одного раза. Если вы хотите избежать этого, возможно:

Map<DateTime, List<Client>> clientsByRegsitrationDate(Iterable<Client> clients) {
  var result = <DateTime, List<Client>>{};
  for (var client in clients) {
    for (var registration in client.registrations) {
      var list = result.putIfAbsent(registration.date, () => []);
      if (list.isEmpty || !identical(list.last, client)) list.add(client);
    }
  }
  return result;
}

Или просто используйте наборы вместо списков для сбора клиентов:

Map<DateTime, Set<Client>> clientsByRegsitrationDate(Iterable<Client> clients) {
  var result = <DateTime, List<Client>>{};
  for (var client in clients) {
    for (var registration in client.registrations) {
      result.putIfAbsent(registration.date, () => {}).add(client);
    }
  }
  return result;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...