I want to convert my model view list to JSON format using the map.
@override void initState() {
/// model view data in list
List<Model> data = [
Model('A', 'php');
Model('A', 'flutter', 'engineer1');
Model('A', 'flutter', 'engineer2');
Model('B', 'c sharp', 'engineer1');
Model('B', 'c sharp', 'engineer2');
Model('B', 'dot net', 'engineer2');
Model('B', 'php', 'engineer2');
Model('C', 'php', 'engineer2');
Model('C', 'php', 'engineer1'); ];
}
/// model class
Class Model{
Model(this.team, this.projectName, this.engineersName);
String team;
String projectName;
String engineersName;
}
Excepted output:
A team is occurred 3 times but it will show only one time, now A is KEY. And the A team have 2 project names(php, flutter).
The flutter occurred 2 times but it will show only one time. The flutter have 2 engineers(engineer1, engineer2). Same method to team B and C.
When hover on the map variable it will shows KEY by VALUE.
A - {php,flutter{engineer1, engineer2}}
B - {c sharp{engineer1, engineer2}, dot net{engineer1}, php{engineer2}}
C - {php{engineer2, engineer1}}
I tried this way:
@override
void initState() {
/// Here I grouping a only team.(A, B, C).
Map group = {};
For(var element in data){
var existingValue = group[element.team];
group[element.team] = existingValue;
//// Here I tried to change the map type, but I can't to group a team wise formation.
}}
My Output: When I hover on the group variable(Map group = {};), it shows the 3 Keys only. That is A, B, C. The values are not added. Because the map default type is Map<dynamic, dynamic>.
I tried to add the php and flutter values for A key. But I can't to add the list of values to map value. So, I changed to the map type Map<dynamic, List<Map<dynamic, dynamic>>>. It occurred null exception.
*I don't know how to group the project name and engineer name to hierarchy by based on teams.
If there is any other way to achieve this problem? *
CodePudding user response:
Is this what you like?
import "package:collection/collection.dart";
void main(List<String> arguments) {
List<Model> data = [
Model('A', 'php'),
Model('A', 'flutter', 'engineer1'),
Model('A', 'flutter', 'engineer2'),
Model('B', 'c sharp', 'engineer1'),
Model('B', 'c sharp', 'engineer2'),
Model('B', 'dot net', 'engineer2'),
Model('B', 'php', 'engineer2'),
Model('C', 'php', 'engineer2'),
Model('C', 'php', 'engineer1')
];
var group = groupBy(data, (Model e) => e.team).map((key, value) => MapEntry(
key,
groupBy(value, (Model e) => e.projectName).map((key, value) =>
MapEntry(key, value.map((e) => e.engineersName).whereNotNull()))));
print(group);
}
class Model {
String? team;
String? projectName;
String? engineersName;
Model([this.team, this.projectName, this.engineersName]);
}
Output:
{A: {php: (), flutter: (engineer1, engineer2)}, B: {c sharp: (engineer1, engineer2), dot net: (engineer2), php: (engineer2)}, C: {php: (engineer2, engineer1)}}
CodePudding user response:
Love Ivo's answer. Here is an attempt at explicitly defining the data types and going about this task. Here is an example running on dartpad.dev/ where I have used the class defined below to get the output you likely need
class ModelNeeded {
final List<Model> models;
const ModelNeeded({required this.models});
Map<String,Map<String,Set<String>>> toObject(){
Map<String,Map<String,Set<String>>> object = {};
// This will return a Map which has a key that is the team A,B,C
for(var model in models){
// If the key exists i.e team entry exists
if(object.containsKey(model._team)){
// Get data
Map data = object[model._team] as Map;
//Check if project exists in data
if(data.containsKey(model._projectName)){
// Get engineers data
Set engineers = data[model._projectName] as Set<String>;
// Since this is a set the engineer can be added directly
engineers.add(model._engineerName);
}
// If project doesnt exist in data
// Create project
else {
data[model._projectName] = <String>{}..add(model._engineerName);
}
}
else {
// Create
object[model._team] = {
model._projectName : <String>{}..add(model._engineerName)
};
}
}
return object;
}
}