'I need to compare an array to another and create different lists based on that - flutter / dart
I have two arrays in one class (data-- categorydata and storydata). I have another stateless widget where I need to compare these two arrays (their categories) and based on the category, create a different list.
const categorydata = [
CategoryTemplate(screen: 'story', title: 'Calm down', category: 'ca', color: Colors.blue ),
CategoryTemplate(screen: 'story', title: 'Meditation', category: 'me', color: Colors.orange ),
CategoryTemplate(screen: 'story', title: 'Self confidence', category: 'se', color: Colors.green ),
];
const storydata = [
StoryTemplate(
id: 's1',
categoryId: [ 'ca', 'me' ],
title: 'Title 1', ),
StoryTemplate(
id: 's2',
categoryId: [ 'se', 'me' ],
title: 'Title2', ),
];
then my widget and class look like this
import 'package:flutter/material.dart';
import '../models/dummy_data.dart';
class CategoryItem extends StatelessWidget {
final String title;
final Color color;
final String mycategory;
const CategoryItem ({ Key? key, required this.color, required this.title , required this.mycategory}) : super(key: key);
@override
Widget build(BuildContext context ) {
// I WANT TO COMPARE BOTH OF THEM HERE SO I CAN USE THEM FOR CREATING THE WIDGET LISTS
// I CANT FIND A WAY TO OBTAIN category FROM categorydata SO IT CA BE USED TO
// CHECK IF THEY'RE THE SAME AS categoryId FROM storydata. AND AT THE SAME TIME BE
// USED AS itemCount: categoryStories.length.
final categoryStories = storydata.where((story){
return story.categoryId.contains(categoryTotal);
}).toList();
return Container (
margin: const EdgeInsets.only(top: 10, bottom: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(left: 10, bottom: 10),
child: Text(title),
),
Container(
margin: const EdgeInsets.only(left: 10, top: 5, bottom: 15),
child: ListView.builder(
itemBuilder: (ctx, index){
// I'VE TRIED TO INCLUDE IT HERE SO I CAN HAVE THE INDEX TO CHECK
//categorydata BUT IF I DO THAT I LOSE THE VARIABLE FOR itemCount: DUE TO
//SCOPE
final categoryStories = storydata.where((story){
return story.categoryId.contains(categorydata[index].category);
}).toList();
return Text(categoryStories[index].title);
},
itemCount: categoryStories.length,
)
),
],
),
);
}
}
I want to compare these two arrays' categorydata and storydata so I can create new lists based on their categories. If both of them are equal, then the list is created. If I access it at the beginning (outside the listview builder), then I don't know how to access the category in categorydata. If I instead try to access inside the listview, I have the index to check every category in categorydata but I lose the variable to check the item count.
I hope you can help me! Thanks in advance
Solution 1:[1]
If I understand correctly you wanted to have a list of Category Templates with list of associated Story Templates listed in a ListView.
One of the many approaches is to create a Map object like this Map<CategoryTemplate, List<StoryTemplate>> and then pass this to ListView. Now, this is not as neat as it could be as ListView is intended for plain Lists. The way you could approach this is to extend the Category Template to include Story Templates as a instance variable.
In this situation I have decided to provide solution using the Map object I mentioned above as I am unsure of your constraints.
I have created a method that will return a Map<CategoryTemplate, List<StoryTemplate>>called sortByCategories().
Map<CategoryTemplate, List<StoryTemplate>> sortByCategories() {
Map<CategoryTemplate, List<StoryTemplate>> map = {};
for (var categoryTemplate in categorydata) {
final matchingStories = storydata
.where((element) =>
element.categoryId.contains(categoryTemplate.category))
.toList();
map[categoryTemplate] = matchingStories;
}
return map;
}
The above method then can be used to get the item count and then by extracting values and keys alongside index from itemBuilder function we can extract the details. See the Container below from my implementation of build
Container(
height: 300,
margin: const EdgeInsets.only(left: 10, top: 5, bottom: 15),
child: ListView.builder(
itemBuilder: (ctx, index) {
return Card(
color: Theme.of(context).colorScheme.background,
child: Container(
margin: const EdgeInsets.all(15),
child: Column(
children: [
Text(sortByCategories()
.keys
.toList()[index]
.title),
Divider(),
...sortByCategories()
.values
.toList()[index]
.map((storyTemplate) {
return Text(storyTemplate.title);
}),
],
),
),
);
},
itemCount: sortByCategories()?.length,
),
),
The final result I had is this
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Kyan |

