Flutter: applying removeAt to a List with the nested objects - flutter

I have a List that contains nested objects.
List _haha = [
{id: 'aaa'},
{id: 'bbb'},
{id: 'ccc'},
{id: 'ddd'},
];
I want to delete 'aaa' inside the _haha. Currently, I did
int _indexVal = _haha.indexWhere((e) => e['id'] == 'aaa');
And, use this int value to remove the item inside the list. Is there any way that I can use .removeAt with one single line?

Oneliner with .removeAt():
void main() {
List<Map<String, String>> haha = [
{'id': 'aaa'},
{'id': 'bbb'},
{'id': 'ccc'},
{'id': 'ddd'},
];
haha.removeAt(haha.indexWhere((item) => item['id'] == 'aaa'));
}
But, you may be more interested in using the .removeWhere() method.
void main() {
List<Map<String, String>> haha = [
{'id': 'aaa'},
{'id': 'bbb'},
{'id': 'ccc'},
{'id': 'ddd'},
];
haha.removeWhere((item) => item['id'] == 'aaa');
}

Related

Flutter - Get or access to matching map(s) from a List of Maps

Here I have a list of maps.
[
{
'name': 'name1',
'age': 30,
},
{
'name': 'name2',
'age': 20,
},
{
'name': 'name1',
'age': 15,
},
]
I need to access to 'name': 'name1' map from above list.
-- Access or extract maps --
i. e. List[0] and(or) List[2]
How do I do this kind of thing???
You can loop through the list and find items, .where will return list of found item. .firstWhere for single item return.
final data = [
{
'name': 'name1',
'age': 30,
},
{
'name': 'name2',
'age': 20,
},
{
'name': 'name1',
'age': 15,
},
];
final findValue = "name1";
final result = data.where((element) => element["name"] == findValue);
print(result); //({name: name1, age: 30}, {name: name1, age: 15})
result.forEach((element) {
print("${element["name"]} ${element["age"]}");
});
More about List

Dynamically Calculate Time using Loops in Dart

I need to create 96 Map objects in a List with the following key-value pairs
{
'id': 1,
'time': '00:00-00:15',
'slotNumber': '01',
'clicked': false
}
Although this is something that is easily achievable using loops, the main complication starts when it comes to generating the time range. The time key in every object needs to be at an interval of 15 minutes each and should be in a 24-hour format. For example, the next few time ranges need to be 00:15-00:30, 00:30-00:45, 00:45-01:00, and so on. I tried hard to look for a package that would answer all my prayers but couldn't find any.
The final output needs to look something like this:
var kSlots = [
{'id': 1, 'time': '00:00-00:15', 'slotNumber': '01', 'clicked': false},
{'id': 2, 'time': '00:15-00:30', 'slotNumber': '02', 'clicked': false},
{'id': 3, 'time': '00:45-01:00', 'slotNumber': '03', 'clicked': false},
{'id': 4, 'time': '01:00-01:15', 'slotNumber': '04', 'clicked': false},
{'id': 5, 'time': '01:15-01:30', 'slotNumber': '05', 'clicked': false},
{'id': 6, 'time': '01:30-01:45', 'slotNumber': '06', 'clicked': false},
{'id': 7, 'time': '01:45-02:00', 'slotNumber': '07', 'clicked': false},
{'id': 8, 'time': '02:00-02:15', 'slotNumber': '08', 'clicked': false}]
As I now need to generate the time from a given start date which is in String, I tried modifying #jamesdlin 's answer a bit to achieve that. But it throws the following error:
Uncaught Error: FormatException: Invalid date format
08:00
String getTimeRange(int i) {
var midnight = DateTime.parse(DateFormat('HH:mm').format(DateTime.parse('08:00')));
const interval = Duration(minutes: 15);
var start = midnight.add(interval * i);
var end = start.add(interval);
var formatTime = DateFormat('HH:mm').format;
return '${formatTime(start)}-${formatTime(end)}';
}
void main() {
var slots = [
for (var i = 0; i < 20; i += 1)
<String, dynamic>{
'id': i + 1,
'time': getTimeRange(i),
'slotNumber': '${i + 1}'.padLeft(2, '0'),
'clicked': false,
},
];
slots.forEach(print);
}
Loop over an index and use the index as a multiplier for a Duration of 15 minutes.
You then either can add that multiplied Duration to a DateTime representing midnight (if your time ranges represent points in time) or format those Durations directly (if they represent durations).
I assuming that your times represent points in time:
import 'package:intl/intl.dart';
String getTimeRange(int i) {
var midnight = DateTime.utc(2022, 1, 1);
const interval = Duration(minutes: 15);
var start = midnight.add(interval * i);
var end = start.add(interval);
var formatTime = DateFormat('HH:mm').format;
return '${formatTime(start)}-${formatTime(end)}';
}
void main() {
var slots = [
for (var i = 0; i < 8; i += 1)
<String, dynamic>{
'id': i + 1,
'time': getTimeRange(i),
'slotNumber': '${i + 1}'.padLeft(2, '0'),
'clicked': false,
},
];
slots.forEach(print);
}
You can set use the DateTime class instead of String and manipulate it as you desire: https://api.flutter.dev/flutter/dart-core/DateTime-class.html

Flutter/Dart Get All Values Of a Key from a JSON

How can i get all values of a second level key in a JSON?
I need to get all total values as like 409571117, 410559043, 411028977, 411287235
JSON:
{"country":"USA","timeline":
[{"total":409571117,"daily":757824,"totalPerHundred":121,"dailyPerMillion":2253,"date":"10/14/21"},
{"total":410559043,"daily":743873,"totalPerHundred":122,"dailyPerMillion":2212,"date":"10/15/21"},
{"total":411028977,"daily":737439,"totalPerHundred":122,"dailyPerMillion":2193,"date":"10/16/21"},
{"total":411287235,"daily":731383,"totalPerHundred":122,"dailyPerMillion":2175,"date":"10/17/21"}]}
I can able to get first level values but i don't know how to get second level.
final list = [
{'id': 1, 'name': 'flutter', 'title': 'dart'},
{'id': 35, 'name': 'flutter', 'title': 'dart'},
{'id': 93, 'name': 'flutter', 'title': 'dart'},
{'id': 82, 'name': 'flutter', 'title': 'dart'},
{'id': 28, 'name': 'flutter', 'title': 'dart'},
];
final idList = list.map((e) => e['id']).toList(); // [1, 35, 93, 82, 28]
python version of same question: Python: Getting all values of a specific key from json
UPDATE: You must declare the types in map. See below.
Have you tried subsetting on timeline after using jsonDecode?
For example, you format the data as json:
final newList = jsonEncode(
{ "country": "USA", "timeline":[
{ "total": 409571117, "daily": 757824, "totalPerHundred": 121, "dailyPerMillion": 2253, "date": "10/14/21" },
{"total": 410559043, ...
Then you decode the data into the list you want by first subsetting the timeline feature:
final extractedData = jsonDecode(newList) as Map<String, dynamic>;
final newIdList = extractedData['timeline'].map((e) => e["total"]).toList();

Dynamic list not maping from json Data

Dynamic list not maping from json Data
var jsondata = [
{
'value': '1',
'label': 'Red',
},
{
'value': '2',
'label': 'Green',
},
{
'value': '3',
'label': 'Yellow',
},
];
List<Map<String, dynamic>> _items = jsondata;
JSON Data not maping as variable with List<Map<String, dynamic>>.
You can use json_serializabl to parse JSON.
The document of official can teach you to do this.
Sample code from the document of official
Map<String, dynamic> user = jsonDecode(jsonString);
print('Howdy, ${user['name']}!');
print('We sent the verification link to ${user['email']}.');
Ref: https://flutter.dev/docs/development/data-and-backend/json

Flutter: how to return the value by using other value inside the List<Map>

I have a List<Map<String, String>> like below
[
{ 'name': 'John', 'id': 'aa' },
{ 'name': 'Jane', 'id': 'bb' },
{ 'name': 'Lisa', 'id': 'cc' },
]
And, the ID list **List** as ['bb', 'aa']. By using the ID list, I want to return a new list ['Jane', 'John'] as **List _selectedList**.
I have tried to do it with the .**indexWhere**, however, I am stuck on the List where it has more than one value.
How can I return the List only with the name-value when there is more than one value to look for?
void main() {
var a = [
{ 'name': 'John', 'id': 'aa' },
{ 'name': 'Jane', 'id': 'bb' },
{ 'name': 'Lisa', 'id': 'cc' },
];
var b = ['bb', 'aa'];
var c = a.where((m) => b.contains(m['id'])).map((m) => m['name']);
print(c);
}
Result
(John, Jane)
Use a set to filter out the IDs efficiently.
var ids = ["aa", "cc"];
var idSet = Set<String>.from(ids);
var json = [
{ 'name': 'John', 'id': 'aa' },
{ 'name': 'Jane', 'id': 'bb' },
{ 'name': 'Lisa', 'id': 'cc' },
];
var _selectedList = json.where((data) => idSet.contains(data["id"]))
.map((data) => data["name"]).toList();
print(_selectedList);
Here, .where filters out the data where the ID matches one in the input list "IDs". Sets make the process efficient. Then, the resultant objects are passed to .map where the "name" field is extracted. Finally, the whole thing is converted into a list thus returning the list of names.
Output of the above code:
[John, Lisa]