My question is about dart....
the result I got
[{'sam': 8}, {'john': 822}]
I need to convert it into like below
{'sam': 8, 'john': 822}
pls help me.
thanks for reading
Something like this?
void main() {
final listOfMaps = [
{'sam': 8},
{'john': 822},
];
final map = {for (final map in listOfMaps) ...map};
print(map); // {sam: 8, john: 822}
}
Update after example of data has been uploaded
I have made the following example which parses the input you have posted as returns the expected data:
void main() {
final map = {
for (final map in someListOfMaps)
for (final voted in map['voted']! as List<Map<String, String>>)
for (final vote in voted.entries) vote.key: int.parse(vote.value)
};
print(map);
// {60e6956078fb6f42da: 1, 60e6956020d8bf42db: 5, 120d8bf42dffsww66: 1, jd58466daa4dw2: 20, gg4c577x6ad8ds6a: 6}
}
const someListOfMaps = [
{
"voted": [
{"60e6956078fb6f42da": "1"},
{"60e6956020d8bf42db": "5"}
],
"_id": "60e698fe78fb6120d8bf42dd",
"name": "donald"
},
{
"voted": [
{"120d8bf42dffsww66": "1"}
],
"_id": "60e698fe78fb6120d8bf42de",
"name": "barrack"
},
{
"voted": [
{"jd58466daa4dw2": "20"}
],
"_id": "60e698fe78fb6120d8bf42df",
"name": "malan"
},
{
"voted": [
{"gg4c577x6ad8ds6a": "6"}
],
"_id": "60e698fe78fb6120d8bf42e0",
"name": "kuma"
}
];
This is a longer approach and probably more understandable.
// the result I got [{'sam': 8}, {'john': 822}]
// I need to convert it into like below {'sam': 8, 'john': 822}
void main() {
final mapList = [{'sam': 8}, {'john': 822}];
print(mapListToJustMap(mapList)); // output: {sam: 8, john: 822}
// The <int> is not required
print(genericMapListToJustMap<int>(mapList)); // output: {sam: 8, john: 822}
}
Map<String, int> mapListToJustMap(List<Map<String, int>> mapList) {
// Create a new empty map object
final newMap = <String, int>{};
// Iterate through the mapList input
for (final singleMap in mapList) {
// add the current iteration to the new map object
newMap.addAll(singleMap);
}
return newMap;
}
// A generic approach
Map<String, T> genericMapListToJustMap<T>(List<Map<String, T>> mapList) {
// Create a new empty map object
final newMap = <String, T>{};
// Iterate through the mapList input
for (final singleMap in mapList) {
// add the current iteration to the new map object
newMap.addAll(singleMap);
}
return newMap;
}
Related
This may be a fundamental question but I'm trying to calculate tax from the JSON data below. However, I get this message every time I try to print the result.
Uncaught Error: TypeError: Instance of 'JsLinkedHashMap<String, Object>': type 'JsLinkedHashMap<String, Object>' is not a subtype of type 'int'
void main() {
double tax = 0.0;
int index = 0;
Map<String, dynamic> test = {
"data": {
"cartItem": [
{
"id": 30,
"productName": "Mango",
"price": 100.0,
"tax": 10.0,
"quantity": 7,
"mainImage": "http://3.109.206.91:8000/static/product_module/product/png-clipart-slice-of-mango-mango-tea-fruit-mango-game-food_HSPnZGK.png",
"totalPrice": 700.0
}
],
"grandTotal": 700.0
}
};
for(index in test['data']['cartItem']) {
tax += (test['data']['cartItem'][index]['tax'] / 100.0);
}
print(tax);
}
The reason behind running a loop is that there may be more than one object inside the data list.
Your code is incorrect.
void main() {
double tax = 0.0;
int index = 0;
Map<String, dynamic> test = {
"data": {
"cartItem": [
{
"id": 30,
"productName": "Mango",
"price": 10.0,
"tax": 10.0,
"quantity": 7,
"mainImage":
"http://3.109.206.91:8000/static/product_module/product/png-clipart-slice-of-mango-mango-tea-fruit-mango-game-food_HSPnZGK.png",
"totalPrice": 700.0
}
],
"grandTotal": 700.0
}
};
for (final cartItem in test['data']['cartItem']) {
tax += (cartItem['tax'] as num) / 100.0;
}
print(tax);
}
I want to convert a List<List<Map<String, String>>> into List<List> a custom class, how to achieve this in dart.
How to convert this
List<List<Map<String, String>>> = [
{
"course_name": "Estimation & Quantity Surveying",
"credit": "4",
"hours": "40",
},
{
"course_name": "IDP - Industrial Design Project phase II",
"credit": "4",
"hours": "40",
}
],
[
{
"course_name": "Data Base Management System",
"credit": "4",
"hours": "40",
},
{
"course_name": "Estimation & Quantity Surveying",
"credit": "4",
"hours": "40",
},
],
];
into
List<List<StudentTimeTable>>
This is my custom class
class StudentTimeTable{
final String courseName;
final String credit;
final String hours;
}
Something like this would do the trick:
class StudentTimeTable {
final String courseName;
final String credit;
final String hours;
StudentTimeTable.fromMap(Map<String, String> map)
: courseName = map['course_name'],
credit = map['credit'],
hours = map['hours'];
#override
String toString() =>
'StudentTimeTable(courseName = $courseName, credit = $credit, hours = $hours)';
}
void main() {
List<List<Map<String, String>>> input = [
[
{
"course_name": "Estimation & Quantity Surveying",
"credit": "4",
"hours": "40",
},
{
"course_name": "IDP - Industrial Design Project phase II",
"credit": "4",
"hours": "40",
}
],
[
{
"course_name": "Data Base Management System",
"credit": "4",
"hours": "40",
},
{
"course_name": "Estimation & Quantity Surveying",
"credit": "4",
"hours": "40",
},
],
];
List<List<StudentTimeTable>> output = [
...input.map(
(subList) => [...subList.map((map) => StudentTimeTable.fromMap(map))])
];
output.forEach(print);
// [StudentTimeTable(courseName = Estimation & Quantity Surveying, credit = 4, hours = 40), StudentTimeTable(courseName = IDP - Industrial Design Project phase II, credit = 4, hours = 40)]
// [StudentTimeTable(courseName = Data Base Management System, credit = 4, hours = 40), StudentTimeTable(courseName = Estimation & Quantity Surveying, credit = 4, hours = 40)]
}
Explanation of what going on!
The solution makes use of "spread operator" which you can read more about here:
https://dart.dev/guides/language/language-tour#spread-operator
In shot, it is a easy way to create a new list and take all elements in an iterable and put into the list.
So lets see what I do:
List<List<StudentTimeTable>> output = [...input.map((subList) => ...)]
Here we define a new list which are filled with the elements from input.map. The map method are used to take each element in the input and convert it to something else. In our case we want to convert each element in our input (which are also a List) from List<Map<String, String>> to List<StudentTimeTable>
We are then mapping each List<Map<String, String>> to the value from this:
[...subList.map((map) => StudentTimeTable.fromMap(map))]
Which returns a list filled with the elements from the iterator returned from subList.map. The purpose of this map is to convert Map<String, String> into StudentTimeTable.
This is done by calling our new constructor which takes a Map<String, String>:
StudentTimeTable.fromMap(Map<String, String> map)
: courseName = map['course_name'],
credit = map['credit'],
hours = map['hours'];
The same code could have been written something like this which is properly easier to read:
final output = <List<StudentTimeTable>>[];
for (final sublist in input) {
final studentTimeTableSubList = <StudentTimeTable>[];
for (final map in sublist) {
studentTimeTableSubList.add(StudentTimeTable.fromMap(map));
}
output.add(studentTimeTableSubList);
}
And a third way would be something like this which uses "collection for" from the same link about "spread operator":
final output = [
for (final sublist in input)
[for (final map in sublist) StudentTimeTable.fromMap(map)]
];
I have a Dart class that I am using as a node class for a tree data structure.
My goal here is to encode objects of this class and its child nodes recursively.
I have a toJson() method that takes the child Nodes List and calls jsonencode on them.
class Node{
String name;
Map<String, String> attributes;
List<Node> children = List<Node>();
Node(this.name, attributes) {
this.attributes = attributes;
this.children = List<Node>();
}
Node.fromJson(Map<dynamic,dynamic> _map) {
this.name = _map['name'];
this.children = new List<Node>();
this.attributes = _map['attributes'][0];
for(var i = 0; i < _map['children'].length;i++){
Node temp = new Node.fromJson(_map['children'][i]);
this.addChild(temp);
}
}
Map<String, dynamic> toJson() => {
'name': name,
'attributes': [attributes],
'children': [
...this.children.map(jsonEncode)
]
};
}
I have a unit test i created to test this functionality:
Node nodeMap = {
"name": "Name",
"attributes": [
{"#htag1": "tagval1"}
],
"children": [
{
"name": "NameChild1",
"attributes": [
{"#htag2": "tagval2"}
],
"children": []
},
{
"name": "NameChild2",
"attributes": [
{"#htag3": "tagval3"}
],
"children": []
}
]
};
UNode unodeInst = new UNode.fromJson(nodeMap);
// Act
var nodeCreate = nodeInst.toJson();
// Assert
expect(nodeCreate, equals(nodeMap));
Here is the output of my unit test
Expected: {
'name': 'Name',
'attributes': [{'#htag1': 'tagval1'}],
'children': [
{
'name': 'NameChild1',
'attributes': [{'#htag2': 'tagval2'}],
'children': []
},
{
'name': 'NameChild2',
'attributes': [{'#htag3': 'tagval3'}],
'children': []
}
]
}
Actual: {
'name': 'Name',
'attributes': [{'#htag1': 'tagval1'}],
'children': [
'{"name":"NameChild1","attributes":[{"#htag2":"tagval2"}],"children":[]}',
'{"name":"NameChild2","attributes":[{"#htag3":"tagval3"}],"children":[]}'
]
}
Which: at location ['children'][0] is '{"name":"NameChild1","attributes":[{"#htag2":"tagval2"}],"children":[]}' which expected a map
As you see its not encoding my object correctly.
I believe this is happening because when i reclusively call jsonencode this method returns a string that is placed into the children array.
I believe part of my problem is that i dont fully understand the d diffrence between jsonencode() and toJson().
It is my understanding that jsonencode() calls toJson().. but jsonencode() returns a string and toJson() returns a Map<String, dynamic>.. so i think what i want here is to call toJson() recursively and not jsonencode.
Does this sound correct?
But i cannot figure out how to do this on a list in this situation.
I have tried the following
...this.children.map(this.toJson())
but i get "The argument type 'Map<String, dynamic>' can't be assigned to the parameter type 'dynamic Function(Node)'"
...this.children.forEach((element) {element.toJson()})
but i get "Spread elements in list or set literals must implement 'Iterable'"
Does this mean i have to implement the Iterable interface in my class?
You're just using the map method incorrectly. Use the following instead.
[
...this.children.map((e) => e.toJson())
]
It's also unnecessary to use spread with a literal list or use this. You can simplify the code to just
children.map((e) => e.toJson()).toList()
I have a map like this
Map<String, bool> siSelectedDef = {"1": true, "2": true, "3": false};
I want to loop through the map and check for the key which has a value true, and I want to add those keys inside a List<Map<String, Object>> must
i.e
must contains
[
{
"si" : "1"
},
{
"si" : "2"
}
]
can anyone help me in this, Thanks!
Map<String, dynamic> data = {'a': true, 'b': false, 'c': true};
List<Map<String, dynamic>> _list = [];
data.forEach((key, value) {
if (value) {
_list.add({'si': key});
}
});
print(_list);
please check official doc for more detailed info and other stuffs you can do with Map
I'm trying to build a page showing Open Street Map with routes. I've set up the OSM, and the routes/polylines should be added through a list of LatLng objects (an object consisting of two doubles marking the latitude and longitude of points connected by a line). What I want to do is fetch the user's location, and then get the latitudes and longitudes of the path along the route from the user's location to some other location, through the use of the Graphhopper API.
JSON returned from the API is as follows:
{
"hints":{
"visited_nodes.average":"40.0",
"visited_nodes.sum":"40"
},
"info":{
"copyrights":[
"GraphHopper",
"OpenStreetMap contributors"
],
"took":5
},
"paths":[
{
"distance":689.229,
"weight":408.670174,
"time":496240,
"transfers":0,
"points_encoded":false,
"bbox":[
15.23345,
44.103858,
15.238698,
44.105704
],
"points":{
"type":"LineString",
"coordinates":[
[
15.238079,
44.103858
],
[
15.238369,
44.104135
],
[
15.238698,
44.104337
],
[
15.238349,
44.104658
],
[
15.238155,
44.104889
],
[
15.237904,
44.105114
],
[
15.237713,
44.105236
],
[
15.237051,
44.105388
],
[
15.236858,
44.105457
],
[
15.236894,
44.105388
],
[
15.236866,
44.105314
],
[
15.236739,
44.105209
],
[
15.235663,
44.104713
],
[
15.234928,
44.105129
],
[
15.234886,
44.105037
],
[
15.234913,
44.10476
],
[
15.234786,
44.10476
],
[
15.234449,
44.105039
],
[
15.23355,
44.105704
],
[
15.23345,
44.105639
]
]
},
"legs":[
],
"details":{
},
"ascend":2.619999408721924,
"descend":3.4739990234375,
"snapped_waypoints":{
"type":"LineString",
"coordinates":[
[
15.238079,
44.103858
],
[
15.23345,
44.105639
]
]
}
}
]
}
Basically, I need to create a list of LatLng objects from this JSON ( an example: [LatLng(15.236866, 44.105314), LatLng(15.23355, 44.105704)] ), but, sadly, I have no clue how to do this. Any help, advice or guidance would be greatly appreciated.
I've tried searching through the web and hacking some code together, but I'm afraid that it didn't prove to be of much help.
Future<Points> _fetchCoordinates() async {
final response = await http.get(
'https://graphhopper.com/api/1/route?point=44.1035042,15.2385878&point=44.105091,15.2318734&vehicle=foot&locale=hr&key=<API_KEY>&points_encoded=false&instructions=false',
);
if (response.statusCode == 200) {
return Points.fromJson(json.decode(response.body));
} else {
throw Exception('Error');
}
}
class Points {
List<List<double>> coordinates;
Points({this.coordinates});
factory Points.fromJson(Map<String, dynamic> json) => Points(
coordinates: List<List<double>>.from(json["paths"]["points"]
["coordinates"]
.map((x) => List<double>.from(x.map((x) => x.toDouble())))));
Map<String, dynamic> toJson() => {
"coordinates": List<dynamic>.from(
coordinates.map((x) => List<dynamic>.from(x.map((x) => x))))
};
}
class Routing extends StatelessWidget {
#override
Widget build(BuildContext context) {
return FutureBuilder<Points>(
future: _fetchCoordinates(),
builder: (context, snapshot) {
final List coordinates =
snapshot.hasData ? snapshot.data.coordinates : <LatLng>[];
if (snapshot.hasData) {
return MyCustomMap(
lat: 44.1035042,
lng: 15.2385878,
points: <List of LatLng objects, for example: [LatLng(41.234,
43.465)]>,
);
} else if (snapshot.hasError) {
return [...]
} else
return [...]
},
);
}
}
It appears that there's some error in my code; statement that's returned is located in the "else if (snapshot.hasError)" clause.
Define a LatLng class like this:
class LatLng {
double lat;
double lng;
LatLng(this.lat, this.lng);
}
then you can decode the json like this:
Map<String, dynamic> decoded = json.decode(j);
List<dynamic> co1 = decoded['paths'][0]['points']['coordinates'];
List<LatLng> coords = co1.map((pair) => LatLng(pair[0], pair[1])).toList();
You could still have a Points class that wrapped the List<LatLng>...