Dart split / compress Lists - list

This is the code for my list:
Future<List<Map>> queryDb() async {
List localList;
final db = await database;
final allRows = await db.query(TABLE_FAVORITE);
localList = allRows.toList(growable: true);
localList.removeWhere((item) => item[COLUMN_ISFAVORITE] == 0);
publicFavoriteList = localList;
print(localList);
return localList;
}
whenever it gets called it prints:
[{id: 0, isFavorite: 1}, {id: 1, isFavorite: 1}, {id: 2, isFavorite: 1}, {id: 4, isFavorite: 1}]
How can I "cut" this to
[{0}, {1}, {2}, {4}]

Use map to extract the values from the inner Map objects:
var localValues = localList.map((o) => o['id'] as int).toList();
print(localVales);
// Prints: [0, 1, 2, 4]

Related

Create a map inside a list in Flutter/Dart

I want to create a MAP inside a list.
The result should be something like this
[{date: 0, value: 0}, {date: 1, value: 0}, {date: 2, value: 0}, {date: 3, value: 0}, {date: 4, value: 0}]
This would be the easiest way-
List a=[];
for (int i = 0; i < 5; i++) {
Map ab={};
ab["date"]=i;
ab["value"]=0;
a.add(ab);
}

flutter - how do calculate average the data in list?

I have a List<Comment> about food from users.
It looks like this:
[
{userId: 1,
rating: 4.5
},
{userId: 2,
rating: 4.0
},
{userId: 3,
rating: 3.5
},
{userId: 4,
rating: 3.0
}
...
];
I want to get the average rating. AVERAGE = Number of ratings : total user, how do I apply this in dart?
var values = [
{'userId': 1, 'rating': 4.5},
{'userId': 2, 'rating': 4.0},
{'userId': 3, 'rating': 3.5},
{'userId': 4, 'rating': 3.0}
];
var result = values.map((m) => m['rating']).reduce((a, b) => a + b) / values.length;
print(result);
In 2021 dart has the built-in average method from the collection package which can be used on an Iterable.
import 'package:collection/collection.dart';
void main() {
var values = [
{'userId': 1, 'rating': 4.5},
{'userId': 2, 'rating': 4.0},
{'userId': 3, 'rating': 3.5},
{'userId': 4, 'rating': 3.0}
];
var result = values.map((m) => m['rating']!).average;
print(result); // prints 3.75
}
You might also be interested in the .sum method from the same package.
I did this by adding the values with the fold function and then dividing by the total. Here is an example:
var values = [
{'userId': 1, 'rating': 4.5},
{'userId': 2, 'rating': 4.0},
{'userId': 3, 'rating': 3.5},
{'userId': 4, 'rating': 3.0}
];
List<double> ratings = values.map((e) => e.price!).toList();
double sum = ratings.fold(0, (p, c) => p + c);
if (sum > 0) {
double average = sum / ratings.length;
}

Google Charts: Why am I getting two select events when I have animation turned on

I attach a select event to charts -- a column chart and a pie chart
When I turn on animation, I get two select events for a single column select action from the column chart (but just one, correctly, from the pie chart, which doesn't animate).
For the column chart, the first event returns the correct selection data [{column:1, row:1}], but the second event returns an empty array.
With animation turned off (commented out) I get the correct response, namely only one event when a user selects a column.
Has anyone seen this? What do I do? I haven't found any value that lets me even differentiate whether the event is occurring in the presence of animation, or any other logical way to at least filter out the rogue second event. Obviously I would like to suppress the incorrect second event when animation is turned on.
Here's the animation spec:
let options = {
animation:{
startup: true,
duration: 500,
easing: 'out',
},
the 'select' event on a ColumnChart seems to be working fine with animation here,
see following working snippet...
is there more you can share?
are you creating the charts directly or using the ChartWrapper class?
which packages are you using, 'corechart'?
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable();
data.addColumn('timeofday', 'Time of Day');
data.addColumn('number', 'Motivation Level');
data.addColumn('number', 'Energy Level');
data.addRows([
[{v: [8, 0, 0], f: '8 am'}, 1, .25],
[{v: [9, 0, 0], f: '9 am'}, 2, .5],
[{v: [10, 0, 0], f:'10 am'}, 3, 1],
[{v: [11, 0, 0], f: '11 am'}, 4, 2.25],
[{v: [12, 0, 0], f: '12 pm'}, 5, 2.25],
[{v: [13, 0, 0], f: '1 pm'}, 6, 3],
[{v: [14, 0, 0], f: '2 pm'}, 7, 4],
[{v: [15, 0, 0], f: '3 pm'}, 8, 5.25],
[{v: [16, 0, 0], f: '4 pm'}, 9, 7.5],
[{v: [17, 0, 0], f: '5 pm'}, 10, 10],
]);
var view = new google.visualization.DataView(data);
view.setColumns([{sourceColumn:0, type: 'string', calc: 'stringify'}, 1]);
var options = {
animation:{
startup: true,
duration: 500,
easing: 'out',
},
hAxis: {
title: 'Time of Day',
format: 'h:mm a',
viewWindow: {
min: [7, 30, 0],
max: [17, 30, 0]
}
},
isStacked: true,
title: 'Motivation and Energy Level Throughout the Day',
vAxis: {
title: 'Rating (scale of 1-10)'
}
};
var chartCol = new google.visualization.ColumnChart(document.getElementById('column_div'));
var chartPie = new google.visualization.PieChart(document.getElementById('pie_div'));
google.visualization.events.addListener(chartCol, 'select', function () {
showSelection(chartCol);
});
google.visualization.events.addListener(chartPie, 'select', function () {
showSelection(chartPie);
});
function showSelection(sender) {
document.getElementById('msg_div').innerHTML += (new Date()).getTime() + ' -- ' + JSON.stringify(sender.getSelection()) + '<br/>';
}
chartCol.draw(data, options);
chartPie.draw(view, {
legend: 'none',
theme: 'maximized'
});
},
packages: ['corechart']
});
div {
padding: 6px 6px 6px 6px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="column_div"></div>
<div id="pie_div"></div>
<div id="msg_div"></div>

Show/hide lines in Google Chart and show grayed text in legend

Trying to do a chart to show/hide the lines on click (I think the original code is from #asgallant), but it only works after the first interaction.
PS.: Is it possible to gray out the text in the legend too?
FIDDLE
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable
([
['Time', 'One', 'Two', 'Three', 'Four', 'Five'],
['05/2013', 0, 3, 0, 0, 8],
['06/2013', 0, 3, 1, 0, 7],
['07/2013', 0, 3, 1, 0, 7],
['08/2013', 0, 3, 1, 0, 7],
['09/2013', 0, 3, 1, 0, 7],
['10/2013', 0, 3, 1, 0, 7],
['11/2013', 0, 3, 1, 0, 7],
['12/2013', 0, 3, 1, 0, 7],
['01/2014', 0, 3, 1, 0, 7],
['02/2014', 0, 3, 1, 0, 7],
['03/2014', 0, 3, 1, 0, 7],
['04/2014', 0, 2, 1, 0, 7],
['05/2014', 0, 2, 1, 0, 7]
]);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
var options = {
chartArea: {width: '80%', height: '70%'},
fontSize: ['13'],
lineWidth: 3,
pointSize: 10,
series: series
};
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row === null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
}

What's an efficient way to filter this array?

My data structure is
companies = [
{name: 'A', ramps: [1, 2]},
{name: 'B', ramps: [3, 4, 5]}
...
]
ramps = [
{id: 1, division: 'accounting', amount: 500},
{id: 2, division: 'sale', amount: 200},
...
]
My goal is to end up with the following data:
groupedByDivision = [
{division: accounting, total: 12000},
{division: sales, total: 6500},
..
]
My first brute-force approach is something like this (note: I've extended Ember.Array with this flatten method:
var ramps = this.get('controller.companies') // this is the array of companies
.get('model')
.mapProperty('ramps')
.flatten();
var temp = {}, data = [];
$.each(ramps, function(index, ramp) {
if ( !(ramp.billingDiv in tempCompanies) ) {
temp[ramp.billingDiv] = ramp.feeChange;
} else {
temp[ramp.billingDiv] += ramp.feeChange;
}
});
$.each(temp, function(division, amount) {
data.push({
'category': division,
'count': amount
});
});
return data;
Any other suggestions? I'm not too familiar with the Ember.Array methods yet, so I'm not aware of all their use cases.