So I have two lists that I each mapped to get the ints, and then I used a reduce function to total them.
I now need just both those totals in a new list, like a totalsList made up of TotalsEntry's or something.
How can this be done?
List<int> listOfOnlyPrices = [];
List<int> listOfOnlyExpenses = [];
int totalSales;
int totalExpenses;
void totalSalesWidget() {
listOfOnlyPrices = items.map<int>((SaleEntry int) =>
int.price).toList();
totalSales = listOfOnlyPrices.reduce((a, b) => a + b);
}
void totalExpensesWidget() {
listOfOnlyExpenses = expenseList.map<int>((ExpenseEntry int) => int.priceEx).toList();
totalExpenses = listOfOnlyExpenses.reduce((a, b) => a + b);
}
All of this works fine btw. I can use totalSales and totalExpenses already within the app.
If I understand you correctly, the following should already do the job:
List<int> get totalsList => [totalSales, totalExpenses];
Related
I am using fold on an array which hasn't been assign to a variable and want to check whether the element is the last value. With a conventional for loop I can do this:
List<int> ints = [1, 2, 3];
int sum = 0;
for (int num in ints]) {
if (num != ints.last) {
sum = sum + num;
}
}
print(sum);
Is it possible to do this with fold instead?
int foldSum = [1, 2, 3].fold(0, (int prev, element) => prev + element);
print(foldSum);
I can't find any way of check when fold is at the last value. Note: this is a simplified example of my problem and the reason the list isn't assigned to a variable (allowing me to use .last) is because it is the result of a call to .map().
For completeness, below is the actual code (which won't obviously won't be runnable in isolation but will help illustrate my problem) I am trying to convert to use .map and .fold:
String get fieldsToSqlInsert {
String val = "";
for (Column column in columns) {
if (data.containsKey(column.name)) {
val = '$val "${data[column.name]}"';
} else {
val = "$val NULL";
}
if (column != columns.last) {
val = "$val,";
}
}
return val;
}
But it doesn't work because I don't know how to check when fold is at the final element:
String get fieldsToSqlInsert => columns
.map((column) =>
data.containsKey(column.name) ? data[column.name] : "NULL")
.fold("", (val, column) => column != columns.last ? "$val," : val);
If you simply want to exclude the last element from further calculation, you can just use take to do so:
String get fieldsToSqlInsert => columns.take(columns.length - 1)...
How can I find the closest value in a list, which will return me the higher value?
Example: List of [3,7,12,19] if my value is 8 how can I get the nearest(larger) value 12? i want this logic in dart.
Just filter the List only for the values higher or equal to your number and get the lowest value:
var n = 8; // Number to match
var l = [3, 7, 12, 19]; // List of values
var greater = l.where((e) => e >= n).toList()..sort(); //List of the greater values
print(greater.first); // Print the first value. -> 12
To get Closest Value of number
import 'dart:math';
import 'dart:collection';
void main(){
List<double> value = [1,4,6,3,7,9,12,34,12,-12,-91];
print(value.getCloseValue(8)); // 7
print(value.getCloseValue(6)); // 6
print(value.getCloseValue(-11)); // -12
}
extension on List<num> {
num getCloseValue(num x) {
if (isEmpty) return 0;
Map<num, num> values = {};
forEach((e) {
values[e] = (e - x).abs();
});
var sortedKeys = values.keys.toList(growable:false)
..sort((k1, k2) => values[k1]!.compareTo(values[k2]!));
final sortedMap = LinkedHashMap
.fromIterable(sortedKeys, key: (k) => k, value: (k) => values[k]);
return sortedMap.keys.first;
}
}
List<int> arr = [6, 12, 11, 18, 24,5,6,99,10,9];
arr.sort((a, b) => a.compareTo(b));
print(arr);
print(Utils.getNextLargerNumber(8, arr));
and below is the logic:
static int getNextLargerNumber(int number, List<int> array)
{
for (var i = 0; i < array.length; i++) {
if (number < array[i]) {
return array[i];
}
}
return -1;
}
Mattia's answer is already good enough. (although the list cant have the length 0 and it might be not as efficient, as you have a where() as well as sort() in there). Here is a different approach, that solves those concerns:
Nearest value to target (larger favored)
final nearestLarger = list.isEmpty ? null : list.reduce(
(a, b) => (a-target).abs() < (b -target).abs() ? a : b);
Nearest value to target (smaller favoured)
final nearestSmaller = list.isEmpty ? null : list.reduce(
(a, b) => (a-target).abs() <= (b -target).abs() ? a : b);
Note that both functions retrieve the nearest value to the target, but in case of ambiguity (eg. [3,4,5]) either the bigger or smaller value is favored.
How to create Multidimensional List in dart?. IN other languages we can use array for this But in dart
we use List . SO i find in google I could not found method for Create Multidimensional List in dart ?
Anyone Know create Multidimensional List in dart ?
There are multiple ways to accomplish that. The simplest solution is to create a list of lists like:
void main() {
// Create 5x5 list
List<List<int>> twoDimList = List.generate(5, (_) => List.filled(5, 0));
twoDimList[0][0] = 5;
print(twoDimList);
}
A more efficient way to do it is to use a single list and access it by using two coordinates like the following class I have used in a previous project:
class Grid<T> {
final int length, height;
final List<T> list;
Grid(this.length, this.height) : list = List(length * height);
T get(int x, int y) => list[_getPos(x, y)];
void set(int x, int y, T value) => list[_getPos(x, y)] = value;
int _getPos(int x, int y) => x + (y * length);
}
In javascript it always bothered me people use objects as vectors like {x: 1, y: 2} instead of using an array [1,2]. Access time for the array is much faster than the object but accessing by index is more confusing especially if you need a large array. I know dart has fixed arrays but is there a way to name the offsets of an array like you would a struct or a tuple/record in another language? Define enum/constants maybe?
I'd want something like
List<int> myVector = new List([x,y]);
myVector.x = 5;
is there an equivalent or idiomatic way to do this?
That sounds like a class.
class MyVector {
int x;
int y;
MyVector(this.x, this.y);
}
There is no simpler and more efficient way to create a name-indexed structure at runtime. For simplicity you could usually use a Map, but it's not as efficient as a real class.
A class should be at least as efficient (time and memory) as a fixed length list, after all it doesn't have to do an index bounds check.
In Dart 3.0, the language will introduce records. At that point, you can use a record with named fields instead of creating a primitive class:
var myVector = (x: 42, y: 37);
print(myVector.x);
A record is unmodifiable, so you won't be able to update the values after it has been created.
For me, i see 2 way to do this. I will sort by best in my point of view
Class based method
Here, the approach is to encapsulate your need, in a dedicated object
Pros:
It's encapsultate
You can propose several way to access variable, depend of the need
You can extend functionality without break everything
I love it :p
Cons
More time spend to create class, etc.
Do you really need what i say in pros ?
Maybe weird for js people
example :
class Vector {
int x;
int y;
static final String X = "x";
static final String Y = "y";
Vector({this.x, this.y});
Vector.fromList(List<int> listOfCoor) {
this.x = listOfCoor[0];
this.y = listOfCoor[1];
}
// Here i use String, but you can use [int] an redefine static final member
int operator[](String coor) {
if (coor == "x") {
return this.x;
} else if (coor == "y") {
return this.y;
} else {
// Need to be change by a more adapt exception :)
throw new Exception("Wrong coor");
}
}
}
void main() {
Vector v = new Vector(x: 5, y: 42);
Vector v2 = new Vector.fromList([12, 24]);
print(v.x); // print 5
print(v["y"]); // print 42
print(v2.x); // print 12
print(v2[Vector.Y]); // print 24
}
Enum based method:
You can also defined a "enum" (actually not really implement but will be in the future version) that will contains "shortcut" to your value
Pros
More simple to implement
Is more like your example ;p
Cons
Less extendable
i think is not very pretty
Not OOP think
example:
class Vector {
static final int x = 0;
static final int y = 1;
}
void main() {
List<int> myVector = new List(2);
myVector[Vector.x] = 5;
myVector[Vector.y] = 42;
}
Make your choice ;p
This is only possible with a class in Dart.
There are some open feature requests at http://dartbug.com
introduce struct (lightweight class)
Give us a way to structure Bytedata
If you have reasonably big data structure, you can use "dart:typed_data" as a model and provide lightweight view for the stored data. This way the overhead should be minimal.
For example, if you need 4X4 matrix of Uint8 values:
import "dart:typed_data";
import "dart:collection";
import "package:range/range.dart";
class Model4X4Uint8 {
final Uint8List _data;
static const int objectLength = 4 * 4;
final Queue<int> _freeSlotIndexes;
Model4X4Uint8(int length): _data = new Uint8List((length) * objectLength),
_freeSlotIndexes = new Queue<int>.from(range(0, length));
int get slotsLeft => _freeSlotIndexes.length;
num operator [](int index) => _data[index];
operator []=(int index, int val) => _data[index] = val;
int reserveSlot() =>
slotsLeft > 0 ? _freeSlotIndexes.removeFirst() : throw ("full");
void delete(int index) => _freeSlotIndexes.addFirst(index);
}
class Matrix4X4Uint8 {
final int offset;
final Model4X4Uint8 model;
const Matrix4X4Uint8(this.model, this.offset);
num operator [](int index) => model[offset + index];
operator []=(int index, int val) => model[offset + index] = val;
void delete() => model.delete(offset);
}
void main() {
final Model4X4Uint8 data = new Model4X4Uint8(100);
final Matrix4X4Uint8 mat = new Matrix4X4Uint8(data, data.reserveSlot())
..[14] = 10
..[12] = 256; //overlow;
print("${mat[0]} ${mat[4]} ${mat[8]} ${mat[12]} \n"
"${mat[1]} ${mat[5]} ${mat[9]} ${mat[13]} \n"
"${mat[2]} ${mat[6]} ${mat[10]} ${mat[14]} \n"
"${mat[3]} ${mat[7]} ${mat[11]} ${mat[15]} \n");
mat.delete();
}
But this is very low level solution and can easily create sneaky bugs with memory management and overflows.
You could also use an extension on List to create aliases to specific indexes.
Although it will be difficult to set up mutually exclusive aliases, in some cases, it may be a simple solution.
import 'package:test/test.dart';
extension Coordinates<V> on List<V> {
V get x => this[0];
V get y => this[1];
V get z => this[2];
}
void main() {
test('access by property', () {
var position = [5, 4, -2];
expect(position.x, 5);
expect(position.y, 4);
expect(position.z, -2);
});
}
The Tuple package https://pub.dev/packages/tuple might be what you are looking for when a class is too heavy.
import 'package:tuple/tuple.dart';
const point = Tuple2<int, int>(1, 2);
print(point.item1); // print 1
print(point.item2); // print 2
I am new at Dart; and, I created a List of playing card objects called Deck. I am trying to select a random card, then remove the card from the deck. I am getting duplicates, as it appears subsequent cards are picked before the deck is reduced. How would I handle a future chain of events that will pick 10 unique random cards from the deck?
class Card{
String face;
String suit;
String rank;
String imgSrc;
String holdImgSrc;
Card(
this.face,
this.suit,
this.rank,
this.imgSrc,
this.holdImgSrc
);
}
import 'dart:math' show Random;
Random indexGen = new Random();
getCard1(){
card1 = deck[indexGen.nextInt(deck.length)];
deck.removeWhere((item) => item == card1);
return card1;
}
getCard2(){
card2 = deck[indexGen.nextInt(deck.length)];
deck.removeWhere((item) => item == card2);
return card2;
}
When I try to return a Card Object as a future I get:
new Future((getCard1()))
.then((getCard2()))
.then((getCard3()));
type 'Card' is not a subtype of type '() => dynamic' of 'computation'.
When I try to return the deck List I get:
type 'List' is not a subtype of type '() => dynamic' of 'computation'.
Am i missing the right syntax, flaw in my logic, or do I need to handle the list differently, by maybe watching for changes?
edit to add: The futures syntax works, however, the deletes do not appear to be happening correctly.
I changed the code, to the code suggested by Jim-Y below, except for preloading new Card objects from a List using the second named constructor. The amended code and printout is as follows:
fullDeck[
...
var tenC = new Card.full(17,'10_of_clubs','c','10','10_of_clubs.png','10_of_clubs_h.png');
var tenD = new Card.full(18,'10_of_diamonds','d','10','10_of_diamonds.png','10_of_diamonds_h.png');
var tenS = new Card.full(19,'10_of_spades','s','10','10_of_spades.png','10_of_spades_h.png');
var tenH = new Card.full(20,'10_of_clubs','c','10','10_of_clubs.png','10_of_clubs_h.png');
...]
Deck<Card> deck = new Deck<Card>();
Random indexGen = new Random();
for(var c = 0; c < 20; ++c) {
var card = new Card(c);
deck.add(fullDeck[c]);//List of 52 full card objects
}
for(var i = 0; i < 10; ++i) {
var rnd = indexGen.nextInt(deck.size());
print('${deck.get(rnd).face} Deck size: ${deck.size()}');
}
}
4_of_clubs Deck size: 19
10_of_diamonds Deck size: 18
5_of_clubs Deck size: 17
4_of_spades Deck size: 16
5_of_spades Deck size: 15
10_of_clubs Deck size: 14
10_of_clubs Deck size: 13
3_of_spades Deck size: 12
5_of_diamonds Deck size: 11
3_of_diamonds Deck size: 10
As you can see the 10 of Clubs is printed twice. So, If the 10 was removed in pass 6, why is it still there in pass 7?
If you want to chain the calls this way the methods must return a future:
Caution: I have not tested the code:
// I don't see what type 'Card' actually is from your code
Future<Card> getCard1(){
return new Future(() {
card1 = deck[indexGen.nextInt(deck.length)];
deck.removeWhere((item) => item == card1);
return card1;
});
}
the same for getCard2()
Future<Card> getCard2(){
return new Future(() {
card2 = deck[indexGen.nextInt(deck.length)];
deck.removeWhere((item) => item == card2);
return card2;
});
}
you call it with
getCard1().then((c) => getCard2()).then((c) => print(c));
as getCard1 and getCard2 are essentially the same methods you could combine them to one
List<Card> cards = [];
Future<Card> getCard(int i){
return new Future(() {
cards[i] = deck[indexGen.nextInt(deck.length)]; // not clear what card is
deck.removeWhere((item) => item == card[i]);
return card[i];
});
}
.
getCard(1).then((c) => getCard(2)).then((c) => print(c));
I can't see now why you need to use Futures for this. In the following code, i will try to address a possibly better approach of removing a Card from a deck using Dart's generic features :)
Your original Card class, I extended it for demonstrational purpose:
class Card {
int id;
String face;
String suit;
String rank;
String imgSrc;
String holdImgSrc;
Card(this.id);
Card.full(this.id, this.face, this.suit, this.rank, this.imgSrc, this.holdImgSrc);
}
Then, you could make a generic container for your cards instead of using a simple List.
class Deck<T extends Card> {
List<T> _container = new List<T>();
T get(int index) => _container.removeAt(index);
void add(T item) => _container.add(item);
int size() => _container.length;
}
This would make your example easier to extend later, and you gain much expression power with it.
Then, you could write something like this, to remove 10 random elements from the deck.
void main() {
Deck<Card> deck = new Deck<Card>();
Random indexGen = new Random();
for(var c = 0; c < 20; ++c) {
var card = new Card(c);
deck.add(card);
}
for(var i = 0; i < 10; ++i) {
var rnd = indexGen.nextInt(deck.size());
print('${deck.get(rnd).id} Deck size: ${deck.size()}');
}
}
On this simple example, with these simple card objects there are no duplicates. However, if you need to, you could extend your Deck class with a(n) fGet method what could be a method returning a Future as mentioned before by #Günter.
I hope i gave you some good ideas :)
Cheers