How to rearrange map keys in dart? - flutter

I have a map like below :
{
"Future": [
{
"accountId": 57,
"firstName": "Inez",
"lastName": "Mitchell",
"middleName": "J",
}
],
"Overdue": [
{
"accountId": 5,
"firstName": "Mak",
"lastName": "Mitchell",
"middleName": "M",
}
],
"Due Today": [
{
"accountId": 59,
"firstName": "Jack",
"lastName": "Daniel",
"middleName": "P",
}
]
}
and wanted the map like in below order, Due Today first, Overdue 2nd and Future at last.
{
"Due Today": [
{
"accountId": 59,
"firstName": "Jack",
"lastName": "Daniel",
"middleName": "P",
}
],
"Overdue": [
{
"accountId": 5,
"firstName": "Mak",
"lastName": "Mitchell",
"middleName": "M",
}
],"Future": [
{
"accountId": 57,
"firstName": "Inez",
"lastName": "Mitchell",
"middleName": "J",
}
]
}
also these keys in length are 3 but sometimes we got only two of them means Due Today and Future but we have to make sure order is like 1. Due Today 2. Overdue 3. Future

There is no operation which simply rearranges the iteration order of a normal Dart map.
Dart maps usually default to using LinkedHashMap which orders its element (for example for iteration) in key insertion order.
If a key is already there, changing its value does not change the key's position in the iteration order, but any new key added will end up after all existing keys.
That provides the only avaialble way to change iteration order: Remove the key and add it again, which will put it at the end of the iteration order instead of where it previously was.
So, to reorder a map, the easiest is to create a new map:
var newMap = <String, List<Map<String, String>>>{};
for (var key in ["Due Today", "Overdue", "Future"]) {
if (map.containsKey(key)) newMap[key] = map[key];
}
Then newMap has the keys in the correct order. If you want to update your existing map to the same order, then you can do: map..clear()..addAll(newMap); afterwards.
If you want to avoid the extra map, you can delete keys and re-add them instead.
for (var key in ["Due Today", "Overdue", "Future"]) {
if (map.containsKey(key)) {
var value = map[key];
map.delete(key);
map[key] = value;
}
}
This should remove and re-add each key, if it's there at all, in the order you want them.

var keys = abc.keys.toList()..shuffle();
for(var k in keys) {
print('$k, ${abc[k]}');}

steps you need todo:
convert the map to a temp list
do your edits on the list
clear the map
copy the entries from the list back to map
**
> extension ExtensionsOnMap on Map<String, ChannelItem> {
> void replace(int index, String key, ChannelItem channelItem) {
>
> var tmpLst = this.entries.map((e) => MapEntry(e.key, e.value)).toList();
>
> tmpLst.removeAt(index);
> tmpLst.insert(index, new MapEntry(key, channelItem));
>
> this.clear();
>
> tmpLst.forEach((mapEntry) => this[mapEntry.key] = mapEntry.value);
> }
> }
**

Code:
void main(){
Map map = {
"Future": [
{
"accountId": 57,
"firstName": "Inez",
"lastName": "Mitchell",
"middleName": "J",
}
],
"Overdue": [
{
"accountId": 5,
"firstName": "Mak",
"lastName": "Mitchell",
"middleName": "M",
}
],
"Due Today": [
{
"accountId": 59,
"firstName": "Jack",
"lastName": "Daniel",
"middleName": "P",
}
]
};
for(String key in ['Due Today', 'Overdue', 'Future']){
var value = map[key];
map.remove(key);
map[key] = value;
}
print(map);
}
Output:
{
Due Today: [{
accountId: 59,
firstName: Jack,
lastName: Daniel,
middleName: P
}],
Overdue: [{
accountId: 5,
firstName: Mak,
lastName: Mitchell,
middleName: M
}],
Future: [{
accountId: 57,
firstName: Inez,
lastName: Mitchell,
middleName: J
}]
}

Related

Flutter Sort array by other array values

I have data like this
[{"name": "swimming"},{"name": "Politics"},{"name": "Gamer"}]
and I have profiles like
[
{
"username":"abc",
"passions":[
{
"name":"Snooker"
}
]
},
{
"username":"abc",
"passions":[
{
"name":"Coding"
}
]
},
{
"username":"xyz",
"passions":[
{
"name":"swimming"
}
]
},
{
"username":"abc",
"passions":[
{
"name":"Politics"
},
{
"name":"swimming"
}
]
}
]
What I need to do is show first those profiles whose passions are matching with that first data array and then the other rest remaining will show.
I'm sure there are better ways to do this, but this works.
final passions = [{"name": "swimming"},{"name": "Politics"},{"name": "Gamer"}];
final users =
[
{
"username":"abc",
"passions":[
{
"name":"Snooker"
}
]
},
{
"username":"efg",
"passions":[
{
"name":"Coding"
}
]
},
{
"username":"hij",
"passions":[
{
"name":"swimming"
}
]
},
{
"username":"klm",
"passions":[
{
"name":"Politics"
},
{
"name":"swimming"
}
]
}
];
var matches = [];
users.forEach((u) {
passions.forEach((p) {
if (p['name'] == (u['passions'] as List)[0]['name']) {
matches.add(u['username']);
}
});
});
print(matches.toString());
Just give this function a profile list and
Finally returns the sort list
List passions = [{"name": "swimming"}, {"name": "Politics"}, {"name": "Gamer"} ];
List sortListPrfile(List profiles) {
//profiles is a list of result server
List _items = []; // It will be returned eventually
List _noItemCommon = []; //Items that are not common
for (var profile in profiles) {
for (var passion in passions) {
if (profile["passions"][0]["name"] == passion['name']) {
_items.add(profile);
} else {
_noItemCommon.add(profile);
}
}
}
_items.addAll(_noItemCommon);
return _items;
}
Here is a function that returns the complete list by matches first and by sorted users.
Your code has a nested list object that needs to check for values that way is function has one line more :)
Note: This function is only for your current item which matches object keys. To make it more secure you should add guards.
import 'package:flutter/foundation.dart';
void main() {
final filtered = filteredByMatchesFirst(arr, matches);
for (var value in filtered) {
print(value);
}
}
var matches = <Map<String, dynamic>>[
{"name": "swimming"},
{"name": "Politics"},
{"name": "Gamer"},
];
var arr = <Map<String, dynamic>>[
{
"username": "abc",
"passions": [
{"name": "Snooker"}
]
},
{
"username": "abc",
"passions": [
{"name": "Coding"}
]
},
{
"username": "xyz",
"passions": [
{"name": "swimming"}
]
},
{
"username": "byz",
"passions": [
{"name": "Gamer"}
]
},
{
"username": "abc",
"passions": [
{"name": "Politics"},
{"name": "swimming"}
]
}
];
List<Map<String, dynamic>> filteredByMatchesFirst(
List<Map<String, dynamic>> list,
List<Map<String, dynamic>> matches,
) {
// Sort list by users first.
list.sort((m1, m2) {
return (m1['username'] as String).compareTo(m2['username'] as String);
});
// Filter only match values.
var filtered = list.where((map) {
final passions = map['passions'] as List<Map<String, dynamic>>;
return passions.any((a) => matches.any((b) => mapEquals(a, b)));
}).toList();
// Add the rest to the filtered list without duplicates.
return filtered.followedBy(list).toSet().toList();
}
Output:
{username: abc, passions: [{name: Politics}, {name: swimming}]}
{username: byz, passions: [{name: Gamer}]}
{username: xyz, passions: [{name: swimming}]}
{username: abc, passions: [{name: Snooker}]}
{username: abc, passions: [{name: Coding}]}
Output without matching:
{username: abc, passions: [{name: Snooker}]}
{username: abc, passions: [{name: Coding}]}
{username: abc, passions: [{name: Politics}, {name: swimming}]}
{username: byz, passions: [{name: Gamer}]}
{username: xyz, passions: [{name: swimming}]}

Converting list of map to a list of objects in dart

I am making a request to an API which returns me a response.
final response = await http.get(Uri.parse(requestUrl), headers: headers);
It returns the following response.
{
"meta": {
"upcomingMatchCount": 5,
"inProgressMatchCount": 10,
"completedMatchCount": 5
},
"matchList": {
"matches": [
{
"id": 49944,
"matchTypeId": 15,
"series": {
"id": 2739,
"name": "LV= Insurance County Championship 2021",
"shortName": "LV= Insurance County Championship 2021"
},
"name": "",
"status": "LIVE",
"venue": {
"name": "The Cooper Associates County Ground",
"shortName": "The Cooper Associates County Ground"
},
"homeTeam": {
"isBatting": true,
"id": 55,
"name": "Somerset",
"shortName": "SOM"
},
"awayTeam": {
"isBatting": false,
"id": 46,
"name": "Gloucestershire",
"shortName": "GLO"
},
"currentMatchState": "Live",
"isMultiDay": true,
"matchSummaryText": "Live: Gloucestershire won the toss and elected to bowl.",
"scores": {
"homeScore": "8-293",
"homeOvers": "88.0",
"awayScore": "0-0",
"awayOvers": "0"
},
"liveStreams": [],
"isLive": false,
"currentInningId": 1,
"isMatchDrawn": false,
"isMatchAbandoned": false,
"startDateTime": "2021-04-15T10:00:00Z",
"endDateTime": "2021-04-18T17:00:00Z",
"isWomensMatch": false,
"isGamedayEnabled": false,
"removeMatch": false
},
{
"id": 49942,
"matchTypeId": 15,
"series": {
"id": 2739,
"name": "LV= Insurance County Championship 2021",
"shortName": "LV= Insurance County Championship 2021"
},
"name": "",
"status": "LIVE",
"venue": {
"name": "The Spitfire Ground, St Lawrence",
"shortName": "The Spitfire Ground, St Lawrence"
},
"homeTeam": {
"isBatting": false,
"id": 45,
"name": "Kent",
"shortName": "KEN"
},
"awayTeam": {
"isBatting": true,
"id": 40,
"name": "Yorkshire",
"shortName": "YRK"
},
"currentMatchState": "Live",
"isMultiDay": true,
"matchSummaryText": "Live: Yorkshire won the toss and elected to bat.",
"scores": {
"homeScore": "0-0",
"homeOvers": "0",
"awayScore": "8-358",
"awayOvers": "100.0"
},
"liveStreams": [],
"isLive": false,
"currentInningId": 1,
"isMatchDrawn": false,
"isMatchAbandoned": false,
"startDateTime": "2021-04-15T10:00:00Z",
"endDateTime": "2021-04-18T17:00:00Z",
"isWomensMatch": false,
"isGamedayEnabled": false,
"removeMatch": false
},
]
I am retrieving the match list from this response as follows:
final list = map['matchList']['matches'] as List;
I have a Model class which represents each match from the matches key:
class MatchModel {
int id;
int matchTypeId;
Series series;
String name;
String status;
Venue venue;
HomeTeam homeTeam;
HomeTeam awayTeam;
String currentMatchState;
bool isMultiDay;
String matchSummaryText;
Scores scores;
List<Null> liveStreams;
bool isLive;
int currentInningId;
bool isMatchDrawn;
bool isMatchAbandoned;
String startDateTime;
String endDateTime;
bool isWomensMatch;
bool isGamedayEnabled;
bool removeMatch;
MatchModel(
{this.id,
this.matchTypeId,
this.series,
this.name,
this.status,
this.venue,
this.homeTeam,
this.awayTeam,
this.currentMatchState,
this.isMultiDay,
this.matchSummaryText,
this.scores,
this.liveStreams,
this.isLive,
this.currentInningId,
this.isMatchDrawn,
this.isMatchAbandoned,
this.startDateTime,
this.endDateTime,
this.isWomensMatch,
this.isGamedayEnabled,
this.removeMatch});
MatchModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
matchTypeId = json['matchTypeId'];
series =
json['series'] != null ? new Series.fromJson(json['series']) : null;
name = json['name'];
status = json['status'];
venue = json['venue'] != null ? new Venue.fromJson(json['venue']) : null;
homeTeam = json['homeTeam'] != null
? new HomeTeam.fromJson(json['homeTeam'])
: null;
awayTeam = json['awayTeam'] != null
? new HomeTeam.fromJson(json['awayTeam'])
: null;
currentMatchState = json['currentMatchState'];
isMultiDay = json['isMultiDay'];
matchSummaryText = json['matchSummaryText'];
scores =
json['scores'] != null ? new Scores.fromJson(json['scores']) : null;
if (json['liveStreams'] != null) {
liveStreams = new List<Null>();
json['liveStreams'].forEach((v) {
});
}
isLive = json['isLive'];
currentInningId = json['currentInningId'];
isMatchDrawn = json['isMatchDrawn'];
isMatchAbandoned = json['isMatchAbandoned'];
startDateTime = json['startDateTime'];
endDateTime = json['endDateTime'];
isWomensMatch = json['isWomensMatch'];
isGamedayEnabled = json['isGamedayEnabled'];
removeMatch = json['removeMatch'];
}
How do i map data from the list of matches to the list of my MatchModel? Do let me know if you need anything else, any help will be appreciated.
the thing is the response object which is returned is actually a string, so you need to first convert that to json using like
var json = jsonDecode(response).
Once you have it in json format what you can do is access the list as json['matchList']['matches']. So now you can iterater over it like
List<MatchModel> matches = []
for(var match in json['matchList']['matches']){
matches.add(MatchModel.fromJson(match));
}
Hope it's useful.
I would recommend JSON serialization with code generation. In that way you just need a annotation #JsonSerializable for the class, a constructor and part 'match.g.dart'; at the begin of your file. After this, the json_serializable package will generate the Json-converter-methods/factories for you.
For more information you can use this article: https://flutter.dev/docs/development/data-and-backend/json.
Try this.
var json = jsonDecode(response.body)['matchList']['matches'];
List<MatchModel> matches = List.from(json).map((e) => MatchModel.fromJson(Map.from(e))).toList();

How to match id with current id in array

How I will check current user id == id and show user like or not in UI
"reference":[
{
"id":"123",
"userid"234"
},
{
"id":"1423",
"userid"25534"
},
{
"id":"15423",
"userid"2335534"
},
]
if this is json response try to convert it in models using https://javiercbk.github.io/json_to_dart/
or here is code that can work for u
var reference = [
{"id": "123", "userid": "234"},
{"id": "1423", "userid": "25534"},
{"id": "15423", "userid": "2335534"},
];
var r = reference.firstWhere((e) => e["id"] == "123");
print(r);
// output
{id: 123, userid: 234}

Mongoose nested object not updating 'cannot create field "foo" in element'

I have a similar issue to this question.
I'm trying to create a new field using "findAndUpdate". I've tried all the methods, $set, $push, $addSet... none of them seem to be working and I keep getting the same error.
Here's the code:
router.post('/accept', auth, async (req, res) => {
const useremail = user.email
const originalEvent = await Event.findOneAndUpdate({eventId: 61469041, isOrganizer: true, "attendees.email": useremail},
{"$push":{"attendees.status" : "accepted"}},
{new: true})
res.status(200).json({originalEvent, event})
}
catch (e) {
res.status(400).json({ msg: e.message, success: false });
}
});
Here's the error code:
"Cannot create field 'status' in element {attendees: [ { _id: ObjectId('5f80a02a82dceb2810e0aa66'), email: "bob#gmail.com", name: "Bob" } ]}"
Here's the object I'm trying to update:
{
"organizer": {
"email": "alex#gmail.com",
"name": "Alex"
},
"_id": "5f80a02a82dceb2810e0aa65",
"title": "Go to the beach",
"eventId": 61469041,
"isOrganizer": true,
"user": "5f05f23417ca6ab69ccc4cf2",
"attendees": [
{
"_id": "5f80a02a82dceb2810e0aa66",
"email": "bob#gmail.com",
"name": "Bob"
}
],
"__v": 0,
}
Expected outcome:
{
"organizer": {
"email": "alex#gmail.com",
"name": "Alex"
},
"_id": "5f80a02a82dceb2810e0aa65",
"title": "Go to the beach",
"eventId": 61469041,
"isOrganizer": true,
"user": "5f05f23417ca6ab69ccc4cf2",
"attendees": [
{
"_id": "5f80a02a82dceb2810e0aa66",
"email": "bob#gmail.com",
"name": "Bob",
"status": "accepted"
}
],
"__v": 0,
}
SOLVED with this:
const originalEvent = await Event.findOneAndUpdate({eventId: eventId, "isOrganizer": true,
"attendees": {$elemMatch: {email: useremail}}
},
{ $set: { "attendees.$.status": "accepted"} }
)
res.status(200).json(originalEvent)
}
Referencing attendees.status doesn't make sense because in your schema attendees is not an object (with fields such as status) but an array. But you can do it differently. If you have the index of the attendee you want to mutate, you can do { $set: { "attendees.0.status": "accepted" } }, where 0 is the index in the array.
Also, with regards to the first half of your question, the error you're seeing is because $push works on arrays. So in order for your operation to work, you'd have to first initialize such an object {attendees: { status: [] } }.
If the field is not an array, the operation will fail. (docs)

dart flutter max value from list of objects

Looking for some help how to select oldest age from users in flutter object list...
users = [
{ id: 123, name: 'Bob', age: 25},
{ id: 345, name: 'Joe', age: 44},
...
];
First make sure your list has the correct type and format:
List<Map<String, dynamic>> users = [
{"id": 123, "name": "Bob", "age": 25},
{"id": 345, "name": "Joe", "age": 44},
{"id": 35, "name": "Joxe", "age": 40},
];
Then you can do this:
if (users != null && users.isNotEmpty) {
users.sort((a, b) => a['age'].compareTo(b['age']));
print(users.last['age']);
}
Another way would be:
if (users != null && users.isNotEmpty) {
dynamic max = users.first;
users.forEach((e) {
if (e['age'] > max['age']) max = e;
});
print(max['age']);
}
Another one:
if (users != null && users.isNotEmpty) {
print(users.fold<int>(0, (max, e) => e['age'] > max ? e['age'] : max));
}
And this one requires import 'dart:math':
if (users != null && users.isNotEmpty) {
print(users.map<int>((e) => e['age']).reduce(max));
}
I'd use the list reduce function, docs here.
var oldestUser = users.reduce((currentUser, nextUser) => currentUser['age'] > nextUser['age'] ? currentUser : nextUser)
void main() {
var users = [
{"id": 123, "name": 'Bob', "age": 25},
{"id": 345, "name": 'Joe', "age": 44},
{"id": 35, "name": 'Joxe', "age": 40},
];
users.sort(ageCompare);
print(users.first);
}
int ageCompare(u1, u2) => u2['age'] - u1['age'];
try it on https://dartpad.dartlang.org
or just one-liner
users.sort((Map u1, Map u2) => u2['age'] - u1['age']);
print(users.first);