#dart
#dart
Вопрос:
Я хочу создать простое приложение с именем «Генератор групп пользователей», оно будет генерировать группу в зависимости от списка пользователей и общей группы, которую вы хотите создать. Например, у вас есть 20 человек из списка и вы хотите создать 10 групп из этого списка, приложение автоматически сгенерирует 10 групп, и в каждой группе будет по 2 человека. Вот как я это реализую.
class Person {
final int id;
final String name;
Person({this.id, this.name});
}
List<Person> listPerson = [
Person(id: 1, name: 'Ani'),
Person(id: 2, name: 'Budi'),
Person(id: 3, name: 'Citra'),
Person(id: 4, name: 'Doni'),
Person(id: 5, name: 'Emilia'),
Person(id: 6, name: 'Frasisco'),
Person(id: 7, name: 'Goyu'),
Person(id: 8, name: 'Hani'),
Person(id: 9, name: 'Intan'),
Person(id: 10, name: 'Jeri'),
Person(id: 11, name: 'Karina'),
Person(id: 12, name: 'Lemi'),
Person(id: 13, name: 'Momo'),
Person(id: 14, name: 'Nini'),
Person(id: 15, name: 'Opi'),
Person(id: 16, name: 'Parto'),
Person(id: 17, name: 'Queen'),
Person(id: 18, name: 'Risa'),
Person(id: 19, name: 'Sisca'),
Person(id: 20, name: 'Toni'),
// Person(id: 21, name: 'Ucok'),
// Person(id: 22, name: 'Vani'),
// Person(id: 23, name: 'Wahyu'),
// Person(id: 24, name: 'Xixi'),
];
Map<String, List<Person>> generateGroup(
List<Person> values, {
int generateTotalGroup = 1,
}) {
var tempMap = <String, List<Person>>{};
var tempPersonList = <Person>[];
var totalPersonEveryGroup = 0.0;
final totalPerson = values.length;
values.shuffle();
if (totalPerson % generateTotalGroup == 0) {
totalPersonEveryGroup = values.length / generateTotalGroup;
for (int i = 1; i <= generateTotalGroup; i ) {
var nameGroup = "Group $i";
var selectedPerson = values
.getRange(tempPersonList.length,
tempPersonList.length totalPersonEveryGroup.toInt())
.toList();
tempMap[nameGroup] = selectedPerson;
tempPersonList = [...tempPersonList, ...selectedPerson];
}
} else {
/// Question to StackOverflow
}
return tempMap;
}
void main() {
final result = generateGroup(listPerson, generateTotalGroup: 10);
result.forEach((key,listPerson){
listPerson.forEach((person){
print('key $key || person ${person.name}');
});
});
}
Вывод
key Group 1 || person Emilia
key Group 1 || person Nini
key Group 2 || person Citra
key Group 2 || person Hani
key Group 3 || person Frasisco
key Group 3 || person Queen
key Group 4 || person Goyu
key Group 4 || person Risa
key Group 5 || person Karina
key Group 5 || person Intan
key Group 6 || person Lemi
key Group 6 || person Ani
key Group 7 || person Parto
key Group 7 || person Doni
key Group 8 || person Budi
key Group 8 || person Toni
key Group 9 || person Momo
key Group 9 || person Jeri
key Group 10 || person Sisca
key Group 10 || person Opi
Если общее количество человек можно разделить на необходимое количество групп, это нормально (20 человек / 10 групп = по 2 человека в каждой группе), результат применения — это то, что я ожидал.Но проблема в том, что когда невозможно разделить, я не знаю, как с этим справиться.
Пример, общее количество человек = 24, а общая необходимая группа = 10, если я разделю, это приведет к 2,4. То, что я ожидал, если результат не может быть разделен, выглядит следующим образом :
Ожидание
key Group 1 || person Ani
key Group 1 || person Budi
key Group 1 || person Citra
key Group 2 || person Doni
key Group 2 || person Emilia
key Group 2 || person Frasisco
key Group 3 || person Goyu
key Group 3 || person Hani
key Group 3 || person Intan
key Group 4 || person Jeri
key Group 4 || person Karina
key Group 4 || person Lemi
key Group 5 || person Momo
key Group 5 || person Nini
key Group 6 || person Opi
key Group 6 || person Parto
key Group 7 || person Queen
key Group 7 || person Risa
key Group 8 || person Sisca
key Group 8 || person Toni
key Group 9 || person Ucok
key Group 9 || person Vani
key Group 10 || person Wahyu
key Group 10 || person Xixi
Как я могу сделать, как указано выше, если общее количество человек не может быть разделено на общее количество нужных групп?
Спасибо
Ответ №1:
Попробуйте что-то подобное:
class Person {
final int id;
final String name;
Person({this.id, this.name});
}
List<Person> listPerson = [
Person(id: 1, name: 'Ani'),
Person(id: 2, name: 'Budi'),
Person(id: 3, name: 'Citra'),
Person(id: 4, name: 'Doni'),
Person(id: 5, name: 'Emilia'),
Person(id: 6, name: 'Frasisco'),
Person(id: 7, name: 'Goyu'),
Person(id: 8, name: 'Hani'),
Person(id: 9, name: 'Intan'),
Person(id: 10, name: 'Jeri'),
Person(id: 11, name: 'Karina'),
Person(id: 12, name: 'Lemi'),
Person(id: 13, name: 'Momo'),
Person(id: 14, name: 'Nini'),
Person(id: 15, name: 'Opi'),
Person(id: 16, name: 'Parto'),
Person(id: 17, name: 'Queen'),
Person(id: 18, name: 'Risa'),
Person(id: 19, name: 'Sisca'),
Person(id: 20, name: 'Toni'),
Person(id: 21, name: 'Ucok'),
Person(id: 22, name: 'Vani'),
Person(id: 23, name: 'Wahyu'),
Person(id: 24, name: 'Xixi'),
];
Map<String, List<Person>> generateGroup(
List<Person> values, {
int generateTotalGroup = 1,
}) {
var tempMap = <String, List<Person>>{};
var tempPersonList = <Person>[];
var totalPersonEveryGroup = 0;
final totalPerson = values.length;
values.shuffle();
var extra = totalPerson % generateTotalGroup;
totalPersonEveryGroup = values.length ~/ generateTotalGroup;
for (int i = 1; i <= generateTotalGroup; i ) {
var end = totalPersonEveryGroup;
if (extra > 0) {
extra--;
end ;
}
var nameGroup = "Group $i";
var selectedPerson = values
.getRange(tempPersonList.length,
tempPersonList.length end)
.toList();
tempMap[nameGroup] = selectedPerson;
tempPersonList = [...tempPersonList, ...selectedPerson];
}
return tempMap;
}
void main() {
final result = generateGroup(listPerson, generateTotalGroup: 10);
result.forEach((key,listPerson){
listPerson.forEach((person){
print('key $key || person ${person.name}');
});
});
}
Комментарии:
1. не могли бы вы объяснить мне, что означает эта строка
var end = totalPersonEveryGroup; if (extra > 0) {extra--; end ;}
? я немного запутался в этой строке2.
extra
содержит количество элементов, которых недостаточно для заполнения всей группы. И нам нужно распределить эти элементы по первым группам на 1 элемент. Для этого мы ввели новую переменнуюend
, потому что собираемся изменить ее на единицу для нескольких первых элементов (поэтому мы не меняемtotalPersonEveryGroup
время от времени). Когда мы потратили предмет, мы должны уменьшить количество дополнительных предметов (extra--
) и увеличить количество предметов в текущей группе (end
). И мы делаем это до тех пор, пока у нас не появятся дополнительные элементы, вот почему у нас есть условие (extra > 0
) .
Ответ №2:
Самый простой способ распределить n элементов по k сегментам — циклический перебор.
List<List<T>> distribute<T>(List<T> elements, int buckets) {
var result = [for (var i = 0; i < buckets; i ) <T>[]];
for (var i = 0, b = 0; i < elements.length; i ) {
result[b].add(elements[i]);
b = b 1;
if (b == buckets) b = 0;
}
return resu<
}
Это не даст вам желаемых результатов, когда первые элементы хранятся вместе. Вместо этого он распределит первые элементы с подсчетом количества сегментов в каждый отдельный сегмент, затем добавит следующие элементы с подсчетом количества сегментов в те же сегменты и т.д.
Если вы хотите сохранить элементы вместе, я бы сделал что-то немного более сложное:
List<List<T>> split<T>(List<T> elements, int buckets) {
var n = elements.length;
var min = n ~/ buckets;
var remainder = n.remainder(buckets); // Number of buckets with one more element.
var i = 0;
return [
for (var b = 0; b < buckets; b ) [
for (var j = 0; j < min; j ) elements[i ],
if (--remainder >= 0) elements[i ]
]
];
}