sort 2 dependent dart arrays - flutter

I have got 2 arrays
ids=[GEORGE, RUSTY, RIYAZAT, JAMES PAWNED];
avgscore=[10, 13, 3, 40];
I want the result array to be sorted in descending order wrt marks scored
and both the arrays should be sorted accordingly, the result should be like this
ids should be sorted as [40, 13, 10, 3];
avgscore should be sorted as [JAMES PAWNED, RUSTY, GEORGE, RIYAZAT];

You should make a class which binds your two data together. Then it is easy to sort based on the avgscore value:
class Person {
final String id;
final int avgscore;
Person(this.id, this.avgscore);
#override
String toString() => '$id = $avgscore';
}
void main() {
var ids = ['GEORGE', 'RUSTY', 'RIYAZAT', 'JAMES PAWNED'];
var avgscore = [10, 13, 3, 40];
final persons = List.generate(ids.length, (i) => Person(ids[i], avgscore[i]));
print(persons); // [GEORGE = 10, RUSTY = 13, RIYAZAT = 3, JAMES PAWNED = 40]
persons.sort((p1, p2) => p2.avgscore.compareTo(p1.avgscore));
print(persons); // [JAMES PAWNED = 40, RUSTY = 13, GEORGE = 10, RIYAZAT = 3]
// If you need to split the values into two arrays again
ids = persons.map((p) => p.id).toList();
avgscore = persons.map((p) => p.avgscore).toList();
print(ids); // [JAMES PAWNED, RUSTY, GEORGE, RIYAZAT]
print(avgscore); // [40, 13, 10, 3]
}

personally I think that it would be easier for you if you work with a list of Maps specially if you're planning to have more data and not just 4 in your list
here's an example of what working with a map would look like
void sortMap() {
var temp= {
"GEORGE":10,
"RUSTY":13,
"RIYAZAT":3,
"JAMES PAWNED":40
};
temp = SplayTreeMap.from(
temp, (key1, key2) => temp[key1].compareTo(temp[key2]));
print(temp);
}

Related

How do I get the names of months and years from a DateTime list into a map?

How do I get the names of months and years from a DateTime list into a map?
For example: i have list of DateTime:
[22.01.2022, 24.01.2022, 15.02.2022, 29.03.2023]
I have to get on the way out:
{
"jan22" = "January 2022",
"feb22" = "February 2022"
"mar23" = "March 2023"
}
Lets assume your List is:
List<DateTime> dates = [
DateTime(2022, 07, 01),
DateTime(2022, 08, 04),
];
With intl package, you can do this:
Map<String, String> result = {};
dates.forEach((date) {
var shortMonth = DateFormat("MMM").format(date);
var year = DateFormat("yy").format(date);
var month = DateFormat("MMMM").format(date);
result['$shortMonth$year'] = '$month ${date.year}';
});
print("result= $result"); //result= {Jul22: July 2022, Aug22: August 2022}
You need to parse all the items in the list, and check for each of them that your map doesn't already have that value. I don't know if there is any function that can help you (i.e. maybe using Set instead of Map), but this should not be hard to achieve. Something like (it's almost pseudocode, don't expect to copy&paste and have no errors):
var map = <String, String>{};
var list = <DateTime>[/*your list*/];
for (var date in list){
var key = "${date.month}${date.year}"; //adjust the key as you see fit
if (!map.keys.contains(key)){
map[key] = "${date.month}${date.year}"; //adjust the value stored as you see fit
}
}
Assuming the list like this.
List<DateTime> dates = [
DateTime.parse("2021-12-11"),
DateTime.parse("2020-02-12"),
DateTime.parse("2010-01-23"),
];
Map<String,String> data = {};
Here is how you can convert the list items in the needed format and add them to the Map.
dates.forEach((element) {
String key = DateFormat('MMMdd').format(element).toLowerCase();
String value = DateFormat('MMMM yyyy').format(element);
data[key] = value;
});
print(data);
Output:

Remove duplicate dart

there is a list:
#Koolkid3
#Peetea
#Peetea
#Ruptan
#bulunabu
#ptygma
#ptygma
Here's what to get:
#Koolkid3
#Ruptan
#bulunabu
If there are duplicates, then you need to remove them completely. Therefore, toSet() will not work here. How to do it?
You can convert List to Set to remove duplicates. If needed again convert it into list.
List<String> list = ["a", "v", "a"];
print(list.toSet().toList()); //[a, v]
Removing duplicates and itself
List<String> list = ["a", "v", "a"];
list.removeWhere(
(String s1) => list.where((s2) => s1 == s2).length > 1,
);
print(list); /// [v]
What about the following:
List<String> list = [
"#Koolkid3",
"#Peetea",
"#Peetea",
"#Ruptan",
"#bulunabu",
"#ptygma",
"#ptygma"
];
var occurrenceCount = Map();
list.forEach((x) => occurrenceCount[x] = !occurrenceCount.containsKey(x) ? (1) : (occurrenceCount[x] + 1));
list.retainWhere((element) => occurrenceCount[element] == 1);
print(list);
Use a Map to count occurrence of each item, then use retainWhere to only keep the items that occur once.

How to sort all the data by date in google apps script?

I have retrieved the data from REST API and inserted into google apps script but i am not sure how to sort the data based on the subscription date. I have used the sort() but it is only sorting one column instead of everything. This is my current code and screenshot so far:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mainSheet = ss.getSheetByName("test")
var apiKey = 'test';
var URL_STRING = "";
var url = URL_STRING + "?ApiKey=" + apiKey;
var response = UrlFetchApp.fetch(url);
var json = response.getContentText();
var data = JSON.parse(json);
var firstname = [];
var lastname = [];
var subscriptionDate = [];
for (var i=0;i<data.output.o1.length;i++){
fn=(data.output.o1[i].first_name);
firstname.push([fn]);
ln=(data.output.o1[i].last_name);
lastname.push([ln]);
sd=(data.output.o1[i].subscription_date);
subscriptionDate.push([sd]);
};
mainSheet.getRange(2, 1, firstname.length).setValues(firstname);
mainSheet.getRange(2, 2, lastname.length).setValues(lastname);
mainSheet.getRange(2, 3, subscriptionDate.length).setValues(subscriptionDate);
}
In this case, how about sorting the values when the array for putting to Spreadsheet is created? When this is reflected to your script, it becomes as follows.
From:
var firstname = [];
var lastname = [];
var subscriptionDate = [];
for (var i=0;i<data.output.o1.length;i++){
fn=(data.output.o1[i].first_name);
firstname.push([fn]);
ln=(data.output.o1[i].last_name);
lastname.push([ln]);
sd=(data.output.o1[i].subscription_date);
subscriptionDate.push([sd]);
};
mainSheet.getRange(2, 1, firstname.length).setValues(firstname);
mainSheet.getRange(2, 2, lastname.length).setValues(lastname);
mainSheet.getRange(2, 3, subscriptionDate.length).setValues(subscriptionDate);
To:
var values = data.output.o1.map(({first_name, last_name, subscription_date}) => [first_name, last_name, subscription_date]);
values.sort((a, b) => new Date(a[2]).getTime() > new Date(b[2]).getTime() ? 1 : -1);
mainSheet.getRange(2, 1, values.length, values[0].length).setValues(values);
When values.sort((a, b) => new Date(a[2]).getTime() > new Date(b[2]).getTime() ? 1 : -1); is modified to values.sort((a, b) => new Date(a[2]).getTime() > new Date(b[2]).getTime() ? -1 : 1);, the order of sort direction is changed.
Note:
As other method, when the following script to the bottom of your current script, the sort is run with the column "C".
mainSheet.getRange("A2:C").sort([{ column: 3, ascending: true }]);
In this answer, from your sample image, I supposed that your column "C" is the date object.
References:
map()
sort()
sort(sortSpecObj)
mainSheet.getRange(2,1,mainSheet.getLastRow()-1,3).sort({column:3,ascending:true});

How to sort a list that could contain null values with dart null-safety

I have a list of strings that may contain null values, how do I sort this list?
I'm using Flutter beta channel so null-safety is checked. This is what I have so far:
List<String?> _list = [
'beta',
'fotxtrot',
'alpha',
null,
null,
'delta',
];
_list.sort((a, b) => a!.compareTo(b!));
How do I get this as the outcome:
_list = [
null,
null,
'alpha',
'beta',
'delta',
'fotxtrot',
];
I encountered this recently and built a one line function based on compareTo documentation:
myList.sort((a, b) => a==null ? 1: b==null? -1 : a.compareTo(b));
NB: This brings the null value at the end of the list. In your case just swap -1 and 1 to have them at the front of your List.
You need to modify your sorting method to handle nullable values, not just ignore them. After handling potential nulls you can compare them normally.
_list.sort((a, b) {
if(a == null) {
return -1;
}
if(b == null) {
return 1;
}
return a.compareTo(b);
});
You could also use whereType:
List<String?> _list = [
'c',
'a',
'd',
null,
null,
'b',
];
void main() {
var list = _list.whereType<String>().toList();
list.sort();
print(list); // [a, b, c, d]
}

Rx GroupBy: Remove item or Update exising item not trigger regroup

private static void TestGroupBy()
{
var rxList = new ReactiveList<int>();
Observable.Merge(rxList.ItemsAdded, rxList.ItemChanged.Select(x => x.Sender) ).GroupBy(i => i%3)
.Subscribe(group =>
{
Console.WriteLine(string.Format("--> Group {0} is created", group.Key) );
int child = 0;
group.Subscribe(c =>
{
Console.WriteLine(string.Format(" ------> Adding child {0} to Group {1} - ChildCnt: {2}", c, group.Key, ++child) );
});
});
Console.WriteLine("Add 1 to 10... ");
rxList.AddRange(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
Console.WriteLine("Change item 0 to 11, expect to be moved from group 0, to Group 2 ");
rxList[0] = 11;
Console.WriteLine("Remove item at 0, expect the item to be removed from the group ...");
rxList.RemoveAt(0);
}
I have this piece of code here. I would like the regroup to trigger if item is either removed, or item is replaced with new one. How do I achieve this?
I'm not sure if it's possible to implement item removing using groupBy like you want to do. Take a look at this picture: it seems like you want to alter the elements that have already been pushed to one of the "grouped" streams.
In your case, I would simply create several derived collections (as many as you have groups), with different selectors:
public void Test()
{
var source = new ReactiveList<int>();
var derived1 = source.CreateDerivedCollection(x => x, filter: x => x%3 == 0);
var derived2 = source.CreateDerivedCollection(x => x, filter: x => x%3 == 1);
var derived3 = source.CreateDerivedCollection(x => x, filter: x => x%3 == 2);
}