Dart range operator - flutter

I have been looking at Dart and I was wondering if it has a range operator like the one Kotlin has
https://kotlinlang.org/docs/reference/ranges.html
or anything similar to that.

You could use List.generate, like this:
var list = List.generate(4, (i) => i);
print(list); // prints [0, 1, 2, 3]
Or
List _range(int from, int to) => List.generate(to - from + 1, (i) => i + from);
print(_range(3, 6)); // prints [3, 4, 5, 6]

There is no such operator in Dart at the current time.

For quite some time (since September 2014), Iterable.generate(n) has been available which iterate integers from 0 to n-1. Currently that seems to be the closed you can get to a range() like function.
See the discussion in this issue 7775
Usage example:
Iterable.generate(5).forEach((i) => print(i));

You can use range_type dart package for using ranges.
import 'package:range_type/predefined_ranges.dart';
void main() {
final july = DateTimeRange.parse('[2022-07-01, 2022-08-01)');
final scheduleDate1 = DateTime(2022, 07, 02);
final scheduleDate2 = DateTime(2022, 08, 07);
final workingDays = DateTimeRange.parse('[2022-07-20, 2022-08-15)');
print('Is scheduleDate1 in July? ${july.containsElement(scheduleDate1)}');
print('Is scheduleDate2 in July? ${july.containsElement(scheduleDate2)}');
print('Is workingDays overlaps? ${july.overlap(workingDays)}');
print('workingDays intersection: ${july.intersection(workingDays)}');
print('workingDays union: ${july.union(workingDays)}');
print('july difference workingDays: ${july.difference(workingDays)}');
}

There is no such operator in Dart at the current time.
but try these codes
1.
List<int> range(int from, int from)=>List.generate(10,(i)=>i);
Iterable<int> range(int from,int to,[int stepSize=1]) sync*{
for(int i = from;i<to;i+=stepSize){
yield i;
}
}
Iterable<int> to(int end, [int stepSize = 1]) sync* {
if (this <= end) {
for (var i = this; i < end; i += stepSize) yield i;
} else {
for (var i = this; i > end; i -= stepSize) yield i;
}
}
}

Related

Flutter how to use multiple forloops

I am using this code but sometimes it runs the code in wrong order. Is it possible to wait for each for loop to finish before next one starts?
void changeWeek() {
for (int i = 0; i < newactivities.length; i++) {
int year = DateTime.now().year;
DateTime startDate = DateTime(year, 1, 1);
while (startDate.weekday != DateTime.monday) {
startDate = startDate.add(const Duration(days: 1));
}
for (String weekday in newactivities[i].daylistdone) {
int offset = (int.parse(weekday)) + (int.parse(currentweek) - 1) * 7;
DateTime donedate = startDate.add(Duration(days: offset));
oldDatesDone.add(Timestamp.fromDate(donedate));
}
for (String weekday in newactivities[i].daylist) {
int offset =
(int.parse(weekday) - 1) + (int.parse(currentweek) - 1) * 7;
DateTime notdonedate = startDate.add(Duration(days: offset));
oldDatesNotDone.add(Timestamp.fromDate(notdonedate));
}
for (var i in oldDatesDone) {
oldDatesNotDone.remove(i);
}
finaloldDatesDone = newactivities[i].weekdaysdone + oldDatesDone;
finaloldDatesNotDone = newactivities[i].weekdaysnotdone + oldDatesNotDone;
act.add({
'title': newactivities[i].title,
'days': newactivities[i].daylist,
'notificationidnumber': newactivities[i].notificationidnumber,
'daysdone': myData22,
'weekdaysdone': finaloldDatesDone,
'weekdaysnotdone': finaloldDatesNotDone,
'timelist': newactivities[i].timelist,
'time': newactivities[i].time
});
FirebaseFirestore.instance
.collection(widget.user.user.uid)
.doc(documentName)
.update({"activities": act});
}
}
Or can I do it in another way to solve the code?
Your Firebase update returns a Future, so it is an asynchronous operation. To preserve order of calls, you need to await the result of this call:
void changeWeek() async {
// ...
await FirebaseFirestore.instance
.collection(widget.user.user.uid)
.doc(documentName)
.update({"activities": act});
}
Note that you need do declare the changeWeek() function as async for this to work.

I am facing struggle to get the result for nested object list to probability tree result form. As Following

Can someone help me for a snip of code.
void main() {
List<List<String>> testList = [["a","b","c"], ["1","2"], ["Y","Z"]];
// Result list I want => a1Y, a1Z, a2Y, a2Z, b1Y, b1Z, b2Y, b2Z, c1Y, c1Z, c2Y, c2Z
}
Similar question Generate all combinations from multiple lists
Answer Source: https://stackoverflow.com/a/17193002/6576315
Dart Version:
void generatePermutations(List<List<String>> lists, List<String> result, int depth, String current) {
if (depth == lists.length) {
result.add(current);
return;
}
for (int i = 0; i < lists.elementAt(depth).length; i++) {
generatePermutations(lists, result, depth + 1, current + lists.elementAt(depth).elementAt(i));
}
}
Usage:
List<List<String>> testList = [["a","b","c"], ["1","2"], ["Y","Z"]];
List<String> result = <String>[];
generatePermutations(testList, result, 0, "");
print(result);
// prints: [a1Y, a1Z, a2Y, a2Z, b1Y, b1Z, b2Y, b2Z, c1Y, c1Z, c2Y, c2Z]
Do upvote the original source if it works

split the string into equal parts flutter

There is a string with random numbers and letters. I need to divide this string into 5 parts. And get List. How to do it? Thanks.
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
Should work:
List<String> list = [
'05b37ffe',
'4973959c',
'4d4f2d5c',
'a0c14357',
'49f8cc66',
];
I know there'a already a working answer but I had already started this so here's a different solution.
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
List<String> list = [];
final divisionIndex = str.length ~/ 5;
for (int i = 0; i < str.length; i++) {
if (i % divisionIndex == 0) {
final tempString = str.substring(i, i + divisionIndex);
list.add(tempString);
}
}
log(list.toString()); // [05b37ffe, 4973959c, 4d4f2d5c, a0c14357, 49f8cc66]
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
int d=1
; try{
d = (str.length/5).toInt();
print(d);
}catch(e){
d=1;
}
List datas=[];
for(int i=0;i<d;i++){
var c=i+1;
try {
datas.add(str.substring(i * d, d*c));
} catch (e) {
print(e);
}
}
print(datas);
}
OR
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
int d = (str.length / 5).toInt();
var data = List.generate(d - 3, (i) => (d * (i + 1)) <= str.length ? str.substring(i * d, d * (i + 1)) : "");
print(data);//[05b37ffe, 4973959c, 4d4f2d5c, a0c14357, 49f8cc66]
If you're into one liners, with dynamic parts.
Make sure to import dart:math for min function.
This is modular, i.e. you can pass whichever number of parts you want (default 5). If you string is 3 char long, and you want 5 parts, then it'll return 3 parts with 1 char in each.
List<String> splitIntoEqualParts(String str, [int parts = 5]) {
int _parts = min(str.length, parts);
int _sublength = (str.length / _parts).ceil();
return Iterable<int>
//Initialize empty list
.generate(_parts)
.toList()
// Apply the access logic
.map((index) => str.substring(_sublength * index, min(_sublength * index + _sublength, str.length)))
.toList();
}
You can then use it such as print(splitIntoEqualParts('05b37ffe4973959c4d4f2d5ca0c1435749f8cc66', 5));
splitWithCount(String string,int splitCount)
{
var array = [];
for(var i =0 ;i<=(string.length-splitCount);i+=splitCount)
{
var start = i;
var temp = string.substring(start,start+splitCount);
array.add(temp);
}
print(array);
}

Dart-lang, how can I map List<int> to List<String> with combining elements?

I have a list
final List list = [1, 2, 3, 4, 5, 6, 7];
how can I "map" to the output as a new List like:
"1 and 2",
"3 and 4",
"5 and 6",
"7"
You can achieve that using the following function:
_getComponents(list) => list.isEmpty ? list :
([list
.take(2)
.join(' and ')
]..addAll(_getComponents(list.skip(2))));
Call that function like:
List outPut = _getComponents(yourList);
Explanation:
You are declaring a recursive function called _getComponents
As the first statement you are checking whether the parameter list is empty, if it's empty returning the parameter as is
If the list is not empty
You are taking the first 2 items from the list using take function
You are joining those elements using join function
You are calling the addAll function and supplies the result of recursive _getComponents call as it's argument
And as the parameter of that _getComponents function you are passing the list, after skipping the first 2 elements using the skip function
Answer came off the top of my head but try this:
final List list = [1, 2, 3, 4, 5, 6, 7];
List<String> grouped = [];
for (int i = 0; i < list.length; i++) {
if (i % 2 == 0) {
if (i + 1 < list.length) {
grouped.add("${list[i]} and ${list[i + 1]}");
} else {
grouped.add("${list[i]}");
break;
}
}
}
print(grouped);
This works
main(){
final List list = [1,2,3,4,5,6,7];
final List newList = [];
for(int i = 0; i<list.length; i++){
var string;
if(i+1<list.length){
string = "${list[i]} and ${list[i+1]}";
i++;
}else{
string = "${list[i]}";
}
newList.add(string);
}
print(newList);
}
Write this:
void main(){
final List oldList = [1,2,3,4,5,6,7];
final List newList = [];
for(int i = 0; i<list.length; i += 2){
if(i+1<oldList.length){
newList.add("${oldList[i]} and ${oldList[i+1]}");
}else{
newList.add("${oldList[i]}");
}
}
print(newList);
}

Get most popular value in a list

How I can get the most popular number from a list in dart without using any third party libraries?
var list = [0, 1, 1, 2, 2, 2, 3, 3, 4]; // most popular number is 2
If there are two or more popular numbers then the output should be a List with both values. Example:
One popular number:
var list = [0, 1, 1, 2, 2, 2, 3, 3, 4];
// Output should be [2]
Two or more popular numbers:
var list = [0, 1, 1, 2, 2, 2, 3, 3, 3];
// Output should be [2, 3]
Thank you in advance for your help!
This works...you can optimize it
var list = [1, 1, 2, 2, 3, 4, 5];
list.sort();
var popularNumbers = [];
List<Map<dynamic, dynamic>> data = [];
var maxOccurrence = 0;
var i = 0;
while (i < list.length) {
var number = list[i];
var occurrence = 1;
for (int j = 0; j < list.length; j++) {
if (j == i) {
continue;
}
else if (number == list[j]) {
occurrence++;
}
}
list.removeWhere((it) => it == number);
data.add({number: occurrence});
if (maxOccurrence < occurrence) {
maxOccurrence = occurrence;
}
}
data.forEach((map) {
if (map[map.keys.toList()[0]] == maxOccurrence) {
popularNumbers.add(map.keys.toList()[0]);
}
});
print(popularNumbers);
try this to count each element in list:
var list = [0, 1, 1, 2, 2, 2, 3, 3, 4];
var popular = Map();
list.forEach((l) {
if(!popular.containsKey(l)) {
popular[l] = 1;
} else {
popular[l] +=1;
}
});
I guess I found the solution.
Let me explain it to you:
I had queried through your list and checked whether the keys of the map contains the element or not. If the map does not contain the element as the key then, it will create a key from the element and pass 1 as the value. If the map does contain the element as a key then it will simply increment the value.
Once the map is ready, I had sorted the map values and stored them in a List. From the sorted map values I had taken the last element from the list of sorted values because we had sorted it in ascending order so the most popular value will be at last.
At last, I had queried through the map and check whether the value of the particular key is equal to the popularValue or not. If it is then we are adding the current key and value to the mostPopularValues list.
If I got something wrong please let me know.
void main() {
List list = [0, 1, 1, 1, 2, 2, 2, 3, 3, 4];
List mostPopularValues = [];
var map = Map();
list.forEach((element) {
if (!map.containsKey(element)) {
map[element] = 1;
} else {
map[element] += 1;
}
});
print(map);
// o/p : {0: 1, 1: 3, 2: 3, 3: 2, 4: 1}
List sortedValues = map.values.toList()..sort();
print(sortedValues);
// o/p : [1, 1, 2, 3, 3]
int popularValue = sortedValues.last;
print(popularValue);
// o/p : 3
map.forEach((k, v) {
if (v == popularValue) {
mostPopularValues.add("$k occurs $v time in the list");
}
});
print(mostPopularValues);
// o/p : [1 occurs 3 time in the list, 2 occurs 3 time in the list]
}
Not sure if that's the best solution, but it works pretty well. Let me know if there are any doubts.
final list = [0, 1, 1, 2, 2, 2, 3, 3, 4];
// Count occurrences of each item
final folded = list.fold({}, (acc, curr) {
acc[curr] = (acc[curr] ?? 0) + 1;
return acc;
}) as Map<dynamic, dynamic>;
// Sort the keys (your values) by its occurrences
final sortedKeys = folded.keys
.toList()
..sort((a, b) => folded[b].compareTo(folded[a]));
print('Most popular value: ${sortedKeys.first}'); // 1
print('Second most popular value: ${sortedKeys[1]}'); // 2
I have solved this problem by defining an extension on Iterable:
extension MostPopularItemsExtension<E> on Iterable<E> {
/// Returns the most popular items, where all items in the returned
/// list have the same number of occurances. If [this] is empty, returns an
/// empty list
///
/// Examples:
/// `[1,2,3,2].mostPopularItems() == [2]`
/// `[1,1,2,2].mostPopularItems() == [1,2]`
Iterable<E> mostPopularItems() {
if (isEmpty) return [];
final itemsCounted = <E, int>{};
for (final e in this) {
if (itemsCounted.containsKey(e)) {
itemsCounted[e] = itemsCounted[e]! + 1;
} else {
itemsCounted[e] = 1;
}
}
final highestCount = (itemsCounted.values.toList()..sort()).last;
return itemsCounted.entries
.where((e) => e.value == highestCount)
.map((e) => e.key);
}
}
The basic idea is to count all occurrences of each item in a Map object, get the highest count from this map and then return all items that have that specific number of occurrences.