Фильтрация по айди при наличии общих полей id в третьей модели для двух других моделей Dart?
Пишу учебное приложение на флаттер для рыбалки и встал вопрос о том, как правильно отфильтровать данные из трех моделей, если третья модель имеет в себе значения айди из предыдущих двух.
В документации написано, что нужно использовать метод where, тут увидел похожие вопросы, но в них фильтрация идет лишь по общему айди из двух моделей. В моем же случае их три и две из них не связаны ни по айди, ни по значениям типа String. Каким образом их можно связать между собой и получить уже отфильтрованные параметры?
Вот эти три класса:
//класс модели для снастей
class FishingTackle {
final int id;
final String name;
FishingTackle({this.id, this.name});
}
//класс моделей для наживки
class FishBait {
final int TypeId;
final String BaitName;
FishBait({this.TypeId, this.BaitName});
}
//класс моделей для времени приобритения
class TimeByuing {
final int id;
final int TypeId;
final DateTime time;
TimeByuing({this.id, this.TypeId, this.time});
}
Как видно, класс TimeByuing имеет общие айди с двумя предыдущими, но я никак не могу понять, как их связать между собой и поместить в UI отфильтрованное. Может их нужно как-то по отдельности отфильтровать, а потом уже результат этих фильтраций снова пропустить через where?
class Fishing extends StatelessWidget {
List<FishingTackle> tackle = <FishingTackle>[
FishingTackle(id: 1, name: 'Вентерь'),
FishingTackle(id: 2, name: 'Гарпун'),
FishingTackle(id: 2, name: 'Грузило'),
FishingTackle(id: 1, name: 'Жерлица'),
FishingTackle(id: 1, name: 'Закидушка'),
];
List<FishBait> bait = <FishBait>[
FishBait(TypeId: 1, BaitName: 'Мотыль'),
FishBait(TypeId: 2, BaitName: 'Опарыш'),
FishBait(TypeId: 2, BaitName: 'Короед'),
FishBait(TypeId: 1, BaitName: 'Казара'),
FishBait(TypeId: 1, BaitName: 'Стрекоза'),
];
List<TimeByuing> buying = <TimeByuing>[
TimeByuing(
id: 1, TypeId: 1, time: DateTime.parse('2021-01-15 00:00:00.000')),
TimeByuing(
id: 2, TypeId: 2, time: DateTime.parse('2021-03-21 00:00:00.000')),
TimeByuing(
id: 2, TypeId: 2, time: DateTime.parse('2021-05-15 00:00:00.000')),
TimeByuing(
id: 1, TypeId: 1, time: DateTime.parse('2020-12-15 00:00:00.000')),
TimeByuing(
id: 1, TypeId: 1, time: DateTime.parse('2021-02-18 00:00:00.000')),
];
List<TimeByuing> get buyingProperties {
return buying.where((element) => (element.id == element.id) && (element.TypeId == element.TypeId)).toList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
itemCount: buyingProperties.length,
itemBuilder: (context, index) {
return ExpansionTile(
title: Text(tackle[index].name),
children: [
ListView.builder(
shrinkWrap: true,
itemCount: buyingProperties.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(bait[index].BaitName),
trailing: Text(buying[index].time.toString()),
);
})
],
);
}),
);
}
}
В, JS например, можно сделать нечто подобное, для фильтрации двух списков по айди:
let res = [];
res = arr1.filter(el => {
return !arr2.find(element => {
return element.id === el.id;
});
});
return res;
Можно ли нечто подобное сделать на Dart? Я попробовал вот такой код:
Взять за основу пустой массив куда будет складывать элементы и пустить их по циклу forEach()
List <AllFishes> result = tackle.forEach((el) {
return !bait.where((element) => element.TypeId == el.id);
return result;
});
Ответы (1 шт):
Не оптимальный способ. Создаём список Common из трёх списков, естественно нужно добавить все возможные проверки.
void main() {
List<FishingTackle> tackle = <FishingTackle>[
FishingTackle(id: 1, name: 'Вентерь'),
FishingTackle(id: 2, name: 'Гарпун'),
FishingTackle(id: 3, name: 'Грузило'),
FishingTackle(id: 4, name: 'Жерлица'),
FishingTackle(id: 5, name: 'Закидушка'),
];
List<FishBait> bait = <FishBait>[
FishBait(typeId: 1, baitName: 'Мотыль'),
FishBait(typeId: 2, baitName: 'Опарыш'),
FishBait(typeId: 3, baitName: 'Короед'),
FishBait(typeId: 4, baitName: 'Казара'),
FishBait(typeId: 5, baitName: 'Стрекоза'),
];
List<TimeByuing> buying = <TimeByuing>[
TimeByuing(
id: 5, typeId: 1, time: DateTime.parse('2021-01-15 00:00:00.000')),
TimeByuing(
id: 4, typeId: 2, time: DateTime.parse('2021-03-21 00:00:00.000')),
TimeByuing(
id: 3, typeId: 3, time: DateTime.parse('2021-05-15 00:00:00.000')),
TimeByuing(
id: 2, typeId: 4, time: DateTime.parse('2020-12-15 00:00:00.000')),
TimeByuing(
id: 1, typeId: 5, time: DateTime.parse('2021-02-18 00:00:00.000')),
];
List<Common> common = merge(buying, bait, tackle).toList();
print(common);
}
Iterable<Common> merge(List<TimeByuing> buying, List<FishBait> bait,
List<FishingTackle> tackle) sync* {
for (int i = 0; i < buying.length; i++) {
var name = tackle.firstWhere((v) => v.id == buying[i].id).name;
var baitName =
bait.firstWhere((v) => v.typeId == buying[i].typeId).baitName;
yield Common(
id: buying[i].id,
typeId: buying[i].typeId,
name: name,
baitName: baitName,
time: buying[i].time,
);
}
}
class FishingTackle {
final int id;
final String name;
FishingTackle({this.id, this.name});
}
class FishBait {
final int typeId;
final String baitName;
FishBait({this.typeId, this.baitName});
}
class TimeByuing {
final int id;
final int typeId;
final DateTime time;
TimeByuing({this.id, this.typeId, this.time});
}
class Common {
final int id;
final int typeId;
final String name;
final String baitName;
final DateTime time;
Common({this.id, this.typeId, this.name, this.baitName, this.time});
String toString() => 'Common(id: $id, typeId: $typeId, name: $name, baitName: $baitName, time: $time)';
}
Кода нужен список списков:
void main() {
List<FishingTackle> tackle = <FishingTackle>[
FishingTackle(id: 1, name: 'Вентерь'),
FishingTackle(id: 2, name: 'Гарпун'),
FishingTackle(id: 2, name: 'Грузило'),
FishingTackle(id: 1, name: 'Жерлица'),
FishingTackle(id: 1, name: 'Закидушка'),
];
List<FishBait> bait = <FishBait>[
FishBait(typeId: 1, baitName: 'Мотыль'),
FishBait(typeId: 2, baitName: 'Опарыш'),
FishBait(typeId: 2, baitName: 'Короед'),
FishBait(typeId: 1, baitName: 'Казара'),
FishBait(typeId: 1, baitName: 'Стрекоза'),
];
List<TimeByuing> buying = <TimeByuing>[
TimeByuing(
id: 1, typeId: 1, time: DateTime.parse('2021-01-15 00:00:00.000')),
TimeByuing(
id: 2, typeId: 2, time: DateTime.parse('2021-03-21 00:00:00.000')),
TimeByuing(
id: 2, typeId: 2, time: DateTime.parse('2021-05-15 00:00:00.000')),
TimeByuing(
id: 1, typeId: 1, time: DateTime.parse('2020-12-15 00:00:00.000')),
TimeByuing(
id: 1, typeId: 1, time: DateTime.parse('2021-02-18 00:00:00.000')),
];
List<Common> common = merge(buying, bait, tackle).toList();
print(common);
}
Iterable<Common> merge(List<TimeByuing> buying, List<FishBait> bait,
List<FishingTackle> tackle) sync* {
for (int i = 0; i < buying.length; i++) {
var fishingTackle = tackle.where((v) => v.id == buying[i].id).toList();
var fishBait = bait.where((v) => v.typeId == buying[i].typeId).toList();
yield Common(
id: buying[i].id,
typeId: buying[i].typeId,
fishingTackle: fishingTackle,
fishBait: fishBait,
time: buying[i].time,
);
}
}
class FishingTackle {
final int id;
final String name;
String toString() => 'FishingTackle(id: $id, name: $name)';
FishingTackle({this.id, this.name});
}
class FishBait {
final int typeId;
final String baitName;
String toString() => 'FishBait(typeId: $typeId, baitName: $baitName)';
FishBait({this.typeId, this.baitName});
}
class TimeByuing {
final int id;
final int typeId;
final DateTime time;
TimeByuing({this.id, this.typeId, this.time});
}
class Common {
final int id;
final int typeId;
final List<FishingTackle> fishingTackle;
final List<FishBait> fishBait;
final DateTime time;
Common({this.id, this.typeId, this.fishingTackle, this.fishBait, this.time});
String toString() => 'Common(id: $id, typeId: $typeId, fishingTackle: $fishingTackle, fishBait: $fishBait, time: $time, id: $id)';
}