I am creating a POS where i want to show the items purchased as a text and i intent to store those as a text too. I am separating each item by '\n' character.
Now the problem is that i dont know how to check for text which specifically matches a certain product. I have tried using string.contains method but it is not what i desire.
For example: I have products names like:
Chicken
Chicken Cheese
Now these are two different products but every chicken cheese is going to contain chicken too in it.
So, How can i replace the product
Products are in a list which are further part of a map.
However, for this question; you can assume that all the items are stored as a list, Example below:
['chicken', 120],
['chicken Cheeze', 150],
['chicken Cheeze Pizza', 180],
.......................
Than, down in the code i am saving those products as a string (when tapped upon.).
// Gesture Detector is inside a Galleryview which is further part of a row and expanded widgets,
GestureDetector(
onTap: () {
//bill items is a string Storing all products.
billItems += (item[0] +
' : ' +
item[1].toString() + '\n');
},
P.s: All i want to do is to do something like: "chicken * 3" if chickens are orders 3 times instead of printing it 3 times. Thanks
So, I have came up with a solution, though I don't know how optimal it is or fast.
I first create a product model to serialize it :
class Product {
String name;
double price;
int count;
Product({required this.name, required this.price,this.count=0});
factory Product.fromDynamic(List product) =>
Product(name: product[0], price: product[1]);
Map<String, dynamic> toJson() {
return {"name": name, "price": price,"count":count,};
}
}
So assuming our products are in this form :
final originalProducts = [
['chicken', 120],
['chicken', 135],
['chicken', 140],
['chicken Cheeze', 150],
['chicken Cheeze Pizza', 180],
];
I created a List<Product> :
List<Product> modeledProducts =
List.generate(originalProducts.length, (i) => Product.fromDynamic(originalProducts[i]));
Next I create a temporary List<String> where I will save any duplicate products found (their names), and I create the final List<Products> which will have unique products with their prices summed up :
List<String> duplicates = [];
List<Product> finalProducts = [];
Then we iterate through the modeledProducts to find the duplicates and do the necessary operations :
for (final product in modeledProducts) {
if (!duplicates.contains(product.name)) {
duplicates.add(product.name);
finalProducts.add(product);
} else {
finalProducts.firstWhere((p) => p.name == product.name).price +=
product.price;
finalProducts.firstWhere((p) => p.name == product.name).count++;
}
}
And now you are ready to use your data :
for (final fProduct in finalProducts) {
print(fProduct.toJson());
}
The above will print :
{name: chicken, price: 395, count: 3}
{name: chicken Cheeze, price: 150, count: 1}
{name: chicken Cheeze Pizza, price: 180, count: 1}
Related
I got following problem which I can't solved :(
Scenario: I have a list with Ingredients and I want to compare it with a recipes list which holds a list of ingredients depending on the recipes.
List<RecipeList> recipesList = [
RecipeList(recipeName: "Cake", itemNames: ["banana", "appel"]),
RecipeList(recipeName: "Soup", itemNames: ["potatato", "egg"]),
RecipeList(recipeName: "Sandwich", itemNames: ["Toast", "Sausage", "Ketchup"]),
RecipeList(recipeName: "Pizza", itemNames: ["Tomato", "Mushroom"]),
];
List inventory = ["coke", "egg", "banana", "apple"];
class RecipeList {
String? recipeName;
List<String>? itemNames;
RecipeList({this.recipeName, this.itemNames});
}
I am thankful for any help or idea :D!
Thank you very much for your help,
ReeN
I would start by changing the inventory to be a Set<String>. This will allow you to more efficiently check for subsets using the containsAll method.
You can then call where on the recipesList to get all of the elements where the inventory contains all of the itemNames for the given RecipeList object.
See implementation below:
List<RecipeList> recipesList = [
// fixed misspelling of "apple"
RecipeList(recipeName: "Cake", itemNames: ["banana", "apple"]),
RecipeList(recipeName: "Soup", itemNames: ["potatato", "egg"]),
RecipeList(
recipeName: "Sandwich", itemNames: ["Toast", "Sausage", "Ketchup"]),
RecipeList(recipeName: "Pizza", itemNames: ["Tomato", "Mushroom"]),
];
// change inventory to a Set<String>
Set<String> inventory = {"coke", "egg", "banana", "apple"};
class RecipeList {
String? recipeName;
List<String>? itemNames;
RecipeList({this.recipeName, this.itemNames});
}
void main() {
var results =
recipesList.where((v) => inventory.containsAll(v.itemNames ?? []));
for (var result in results) {
print(result.recipeName);
}
}
one of the approaches that you can take is to loop over the recipesList , hold every element in hand, then access the list in that element and loop over it then you can do whatever comparison you want with the inventory list
I'm trying to retrieve data from a DatabaseEvent event type.
The data I have on the database is this
in this layout
Basically some users id and each user has a a different number of menu orders.
What I want to do is retrieve each order of each user and do something with it.
Right now I'm using
Map data = event.snapshot.value as Map;
but since it's a dynamic cast, it sometimes retrieves the values as a List of Objects and sometimes as a Map of Objects..
For example if the orders number are in order as the picture above (order number 1 and number 2), it retrieves the data like this :
{ZqsrXaqhXbPFgPTvIbnxRNw3bX42: [null, {number: 1, quantity: 3}], tzqjzgzy: [null, {number: 1, quantity: 2}, {number: 2, quantity: 3}]}
as a List and it retrieves a null because there is no order 0. If I change the orders from 1 and 2 to 2 and 3, it gives me the same result but with two nulls at the beginning.
If I change the orders number to more random numbers, it retrieves them correctly as a Map, or more specifically as an _InternalLinkedHashMap<Object?, Object?>.
{ZqsrXaqhXbPFgPTvIbnxRNw3bX42: {12: {number: 12, quantity: 2}, 24: {number: 24, quantity: 3}}}
I want to retrieve it everytime in the same way so I tried casting the snapshot.value in different ways like so
Map<dynamic, Map> data =
event.snapshot.value as Map<dynamic, Map>;
but everytime I do I don't get any data.
This is my code right now
.then((DatabaseEvent event) {
if (event.snapshot.exists) {
Map<dynamic, dynamic> data =
event.snapshot.value as Map;
//sum all orders
Map<int, Map> allOrders = {};
data.forEach((key, userOrders) {
userOrders.forEach((key, order) {
allOrders[order['number']] = {
'number': order['number'],
'quantity': allOrders[order['number']] != null
? allOrders[order['number']]!['quantity'] +
order['quantity']
: 0 + order['quantity'],
};
});
});
return allOrders;
} else {
throw Exception('Error snapshot does not exist');
}
});
It's the first time I use Dart and I'm stuck with a simple thing.
I have a simple Map and I need to remove some items from this map and modify the content.
I have this:
Map<String, List<String>> dataset = {
'apple': ['apple1', 'apple2', 'apple3'],
'pear': ['pear1', 'pear2'],
'ananas': ['ananas1', 'ananas2', 'ananas3'],
'orange': ['orange1', 'orange2', 'orange3', 'orange4'],
};
List<Map<dynamic, String>> fruits = [
{'key': 'pear', 'labelToShow': 'Pear fruit'},
{'key': 'ananas', 'labelToShow': 'My ananas'},
];
and I would like to have this:
Map<String, Map<String, List<String>>> result = {
'pear': {
'values': ['pear1', 'pear2'],
'labelToShow': 'Pear fruit'
},
'ananas': {
'values': ['ananas1', 'ananas2', 'ananas3'],
'labelToShow': 'My ananas'
},
};
So, basically, I need to remove from dataset the items that have the key that it's not included in fruits (in field key) and then I need to add the field labelToShow.
I dont' know ho to do that.
I started removing items from dataset doing so:
dataset.removeWhere((k, v) => k != 'pear' && k != 'ananas');
but I don't like, I would like to loop through fruits.
Can someone please help me?
Thanks a lot
I wouldn't remove anything from dataset. Instead I'd build a new map from scratch, with just the data you want.
How about:
Map<String, Map<String, List<String>>> result = {
for (var fruit in fruits)
fruit["key"]: {
"values": dataset[fruit["key"]],
"labelToShow": fruit["labelToShow"]
}
};
I have a Map of location data like this :
{
'country': 'Japan',
'city': 'Tokyo',
'Latitude': 35.6762,
'Longitude': 139.6503,
'utcOffset': 9
}
witch is the right solution for storing this data and why ?
1) list of maps :
List<Map<String, dynamic>> locations = [
{
'country': 'Japan',
'city': 'Tokyo',
'Latitude': 35.6762,
'Longitude': 139.6503,
'utcOffset': 9
}
];
or multi level data object
var locations = {
{
'country': 'Egypt',
'city': 'Cairo',
'Latitude': 30.033333,
'Longitude': 31.233334,
'utcOffset': 2
},
{
'country': 'Thailand',
'city': 'Bangkok',
'Latitude': 13.7563,
'Longitude': 100.5018,
'utcOffset': 7
},
};
And how to access the data in the 2 cases?
I usually use Map when I want to have key-value pairs because I can directly get the value by key. As a example if you have Map of employes and if you keep the employee id as a key, you can easily access it. Specially for search, or for drop down this is elegant.
Most of the time if I can avoid Map and I will use List because it is very easy for me to handle large amount of data(In flutter I can throw a list to a ListView easily).
But both have there own greatness for depending on the scenario. And note that Map cannot have duplicate key, where List doesnt have like that limitation(Ex: Map can use to avoid duplicate).
var locations = {
{
'country': 'Egypt',
'city': 'Cairo',
'Latitude': 30.033333,
'Longitude': 31.233334,
'utcOffset': 2
},
{
'country': 'Thailand',
'city': 'Bangkok',
'Latitude': 13.7563,
'Longitude': 100.5018,
'utcOffset': 7
},
};
for (var element in locations) {
print(element["country"]);
}
// or
locations.forEach((element) => print(element["country"]));
Here what doc contains about this:
Map<K, V> class
A collection of key/value pairs, from which you retrieve a value using
its associated key.
There is a finite number of keys in the map, and each key has exactly
one value associated with it.
Maps, and their keys and values, can be iterated. The order of
iteration is defined by the individual type of map.
List<E> class
An indexable collection of objects with a length.
Subclasses of this class implement different kinds of lists. The most
common kinds of lists are:
Fixed-length list. An error occurs when attempting to use operations that can change the length of the list.
Growable list. Full implementation of the API defined in this class.
The default growable list, as returned by new List() or [], keeps an
internal buffer, and grows that buffer when necessary. This guarantees
that a sequence of add operations will each execute in amortized
constant time. Setting the length directly may take time proportional
to the new length, and may change the internal capacity so that a
following add operation will need to immediately increase the buffer
capacity. Other list implementations may have different performance
behavior.
You can use both but the first one is preferred as its easier to loop through the items and get the data out.
Not that you can't loop through the second data set, just that its more tedious to loop an array.
Given that your array of objects look like this:
List<Map<String, dynamic>> locations = [
{
'country': 'Japan',
'city': 'Tokyo',
'Latitude': 35.6762,
'Longitude': 139.6503,
'utcOffset': 9
}
];
Suppose you want to take out all the country names and store them in a separate array, It would be really easy and the code should look as follows:
List<String> countryNames = [];
locations.forEach((location) => countryNames.add(location['country]));
You can get data dynamically from a Map creating a this function getData
dynamic getData(Map data, List<String> way) {
dynamic dataTemp = data;
if (way.length > 0) {
for (int x=0; x < way.length; x++) {
dataTemp = dataTemp[way[x]];
}
}
return dataTemp;
}
List<Map<String, dynamic>> locations = [
{
'country': 'Japan',
'city': 'Tokyo',
'Latitude': 35.6762,
'Longitude': 139.6503,
'utcOffset': 9,
'example' : {
'data' : "text",
'number' : 20,
'boolean': false
}
}
];
getData(locations[0],["example","number"]);
output: 20
How to search a list of a class object with one of its property matching to any value in another list of strings
I am able to get filtering based on a single string , but not on a list of strings
final List<shop_cart.ShoppingCart> cartprd = snapshot.documents
.map((f) => shop_cart.ShoppingCart.fromMap(f.data))
.toList();
List<SomeClass> list = list to search;
List<String> matchingList = list of strings that you want to match against;
list.where((item) => matchingList.contains(item.relevantProperty));
If the number of items in list is large, you might want to do:
List<SomeClass> list = list to search;
List<String> matchingList = list of strings that you want to match against;
final matchingSet = HashSet.from(matchingList);
list.where((item) => matchingSet.contains(item.relevantProperty));
Or else just always store the matching values as a hashset.
In case if you want to check for a value in a list of objects . you can follow this :
List rows = [
{"ags": "01224", "name": "Test-1"},
{"ags": "01224", "name": "Test-1"},
{"ags": "22222", "name": "Test-2"},
];
bool isDataExist(String value) {
var data= rows.where((row) => (row["name"].contains(value)));
if(data.length >=1)
{
return true;
}
else
{
return false;
}
}
you can put your own array of objects on rows . replace your key with name . you can do your work based on true or false which is returned from the function isDataExist
As of today, you can't.
(A side note : You can use .where, .singleWhere, .firstWhere. This site explains various list/array methods.)
You can simply use List.where() to filter a list
final List<shop_cart.ShoppingCart> cartprd = snapshot.documents
.where((f) => shop_cart.ShoppingCart.contains(f.data));
var one = [
{'id': 1, 'name': 'jay'},
{'id': 2, 'name': 'jay11'},
{'id': 13, 'name': 'jay222'}
];
int newValue = 13;
print(one
.where((oldValue) => newValue.toString() == (oldValue['id'].toString())));
OUTPUT : ({id: 13, name: jay222})
store output in any variable check if variable.isEmpty then new value is unique either
var checkValue = one
.where((oldValue) => newValue.toString() == (oldValue['id'].toString()))
.isEmpty;
if (checkValue) {
print('Unique');
} else {
print('Not Unique');
}
OUTPUT : Not Unique