How can I know what is the most sold product of a list? flutter-dart - flutter

I have a list of items from the orders by date, so based on its quantity I want to find what is the most sold product.
This is the class for my items
class CartItem{
String id;
String name;
String image;
int quantity;
double price;
CartItem({
this.id,
this.name,
this.image,
this.quantity,
this.price,
});
}
For example:
List<CartItem> list = orders.products;
list.forEach((element => print('${element.name} : ${element.quantity)');
It will print:
Dress : 1
Boots : 2
Trousers : 3
Dress : 2
Trousers : 2
So based on this example, how can I get the most sold product which is 'Trousers' and the sum of its quantity which is 5 for this case.
Thank you in advance.

You can covert the list to a map so you can see distinct items in the list. but rather than assigning the value to the key, if the key already exists, add the value
as:
list.forEach((item) => {
map2[item.name] = item.quantity + (map2[item.name] ?? 0)
});
you will get the output:
{Dress: 3, Boots: 2, Trousers: 5}
then finally you can sort the map like this:
var sortedKeys = map2.keys.toList(growable:false)
..sort((k1, k2) => map2[k2].compareTo(map2[k1]));
LinkedHashMap sortedMap = new LinkedHashMap
.fromIterable(sortedKeys, key: (k) => k, value: (k) => map2[k]);
print(sortedMap);
sorting os mentioned here as well How to sort map value?
then you can get the first element which is the product with the highest orders
hope this helps

Here is another example:
// Dart 2.6.1
main() {
List list = [
{
"name":"Dress",
"quantity" : 1
},{
"name":"Boots",
"quantity" : 2
},{
"name":"Trousers",
"quantity" : 3
},{
"name":"Dress",
"quantity" : 2
},{
"name":"Trousers",
"quantity" : 2
}
];
var products={
};
String mostSelling="";
int quantity=0;
list.forEach((e) {
if(products[e["name"]]== null){
products[e["name"]]= e["quantity"];
} else {
products[e["name"]]+= e["quantity"];
}
if(products[e["name"]] >quantity){
mostSelling= e["name"];
quantity = products[e["name"]];
}
}
);
print("$mostSelling : $quantity");
}
Output:

Related

Flutter Hive data

I am writing data to a Hive box in flutter using the following data from an API;
{
"deliveryAddresses": [
{
"deliveryAddressNo": "1130119",
"deliveryAddressName": "AIRCRAFT MOVEMENTS 2169 (EAA)",
"pointOfServices": [
{
"deliveryAddressNo": "1130119",
"pointOfServiceNo": "1",
"pointOfServiceName": "HT54505",
"pointOfServiceDescription": ""
},
{
"deliveryAddressNo": "1130119",
"pointOfServiceNo": "2",
"pointOfServiceName": "WASH BAY",
"pointOfServiceDescription": ""
}
]
},
{
"deliveryAddressNo": "1130147",
"deliveryAddressName": "TESCO - 6144 - HARROW APOLLO",
"pointOfServices": [
{
"deliveryAddressNo": "1130147",
"pointOfServiceNo": "1",
"pointOfServiceName": "ACTE711092",
"pointOfServiceDescription": ""
}
]
}
]
}
The data is showing in the Box as i expect however, the 2 pointOfServices for the first account show in the Box as NULL. The 2nd customers pointOfService gets written OK.
Any ideas? Is it because there's 2 sets of data on the first account?
Edited:
Showing my Model code for deliveryAddresses;
List<Order> orderListFromJson(String val) => List<Order>.from(json
.decode(val)['deliveryAddresses']
.map((val) => Order.orderInfofromJson(val)));
#HiveType(typeId: 0)
class Order extends HiveObject {
#HiveField(0)
String? deliveryAddressNo;
#HiveField(1)
String? deliveryAddressName;
#HiveField(2)
List<PointOfServices>? pointOfServices;
Order(
{this.deliveryAddressNo, this.deliveryAddressName, this.pointOfServices});
factory Order.orderInfofromJson(Map<String, dynamic> deliveryAddresses) =>
Order(
deliveryAddressNo: deliveryAddresses['deliveryAddressNo'],
deliveryAddressName: deliveryAddresses['deliveryAddressName'],
pointOfServices: List<PointOfServices>.from(
deliveryAddresses['pointOfServices']
.map((pos) => PointOfServices.fromJson(pos))));
}
Points of service model;
List<PointOfServices> posListFromJson(String val) =>
List<PointOfServices>.from(json
.decode(val)['pointOfServices']
.map((val) => PointOfServices.fromJson(val)));
#HiveType(typeId: 1)
class PointOfServices {
#HiveField(7)
String? deliveryAddressNo;
#HiveField(8)
String? pointOfServiceNo;
#HiveField(9)
String? pointOfServiceName;
#HiveField(10)
String? pointOfServiceDescription;
PointOfServices(
{this.deliveryAddressNo,
this.pointOfServiceNo,
this.pointOfServiceName,
this.pointOfServiceDescription});
factory PointOfServices.fromJson(Map<String, dynamic> pointOfServices) =>
PointOfServices(
deliveryAddressNo: pointOfServices['deliveryAddressNo'],
pointOfServiceNo: pointOfServices['pointOfServiceNo'],
pointOfServiceName: pointOfServices['pointOfServiceName'],
pointOfServiceDescription:
pointOfServices['pointOfServiceDescription']);
}
Code that builds the the data and adds to the box;
if (!Hive.isBoxOpen(orderInfoBox)) {
_orderInfo = await Hive.openBox<Order>('orderInfo_db');
_orderInfo.clear();
var result = await OrderNetwork().get();
var resultBody = await json.decode(json.encode(result.body));
List<Order> orderList = List<Order>.empty(growable: true);
orderList.addAll(orderListFromJson(resultBody));
_orderInfo.addAll(orderList);

how to format string data like this '[1,fish#, 15,bird#, 4,horse#]' to '1,fish#15,bird#4,horse#'

how to format string data like this '[1,fish#, 15,bird#, 4,horse#]'
to '1,fish#15,bird#4,horse#'
You need to create the model and map the list to the model
In your case your model class looks like this
class User {
final int user;
final String tag;
User({ required this.user, required this.tag,
});
}
List like this
final List<User> userlist = [User(user: 4, tag: "ahmed#"),User(user: 15, tag: "up#"),];
when you need to get data use like this
userlist[0].tag,//0 is index
example
print(userlist[0].tag,) //this will print **ahmed#**
Simply using join and replaceAll.
export default function App() {
const encode = (source: string[]): string => {
return source.join(",").replaceAll("#,", "#");
};
const decode = (source: string): string[] => {
return source
.split(",")
.reduce((p, n) => [...p, ...n.split("#")], new Array<string>())
.map((e, i) => (i % 2 === 0 ? e : `${e}#`))
.filter((e) => !!e);
};
let source = ["1", "fish#", "15", "bird#", "4", "horse#"];
let sourceEncoded = encode(source);
console.log("encode", sourceEncoded);
// -> 1,fish#15,bird#4,horse#
let sourceDecoded = decode(sourceEncoded);
console.log("decode", sourceDecoded);
// -> ["1", "fish#", "15", "bird#", "4", "horse#"]
return (
<div className="App">
...
</div>
);
}
Code sanbox sample (console).

Flutter Model design pattern

i have a Product Model
class Product {
int id;
String title;
double mrp;
Product(this.id, this.title, this.mrp);
factory Product.fromJson(int id, String title, double mrp) {
return Product(id, title, mrp);
}
}
I have different json structure for API calls when i get json data as response from server -
1st Example
{
"id": 523,
"title": "test",
"mrp": 23.25
}
2nd Example :
{
"id" : 523,
"title" : "test",
"mrp" : 23.25
"discountedPrice" : 23.00
}
3rd Example :
{
"id" : 523,
"title" : "test",
"mrp" : 23.25
"availableForSale" : true
}
4th Example :
{
"id" : 523,
"title" : "test",
"mrp" : 23.25
"firstCharacterTitle" : "T"
}
As you can see i have different new field like discountedPrice firstCharacterTitle availableForSale API structure in different fetching call of API. and it can be many others in other scenario.
What should i do with Product Model in different cases as i have only 3 permanent fields id title mrp but all others are dependent on scenario ? Should i keep increasing field in my model or anything else? What is the best Practise?
Sorry for longer answer.
You have 2 options
adding those extra parameters and make them nullable.
class Product {
int id;
String title;
double mrp;
String? firstCharacterTitle;
Product(this.id, this.title, this.mrp, {this.firstCharacterTitle});
factory Product.fromJson(
int id,
String title,
double mrp, {
String? firstCharacterTitle,
}) {
return Product(id, title, mrp, firstCharacterTitle: firstCharacterTitle);
}
}
Or work with something dynamic
class Product {
int id;
String title;
double mrp;
Map<String, dynamic> extraParams;
Product(this.id, this.title, this.mrp, this.prms);
factory Product.fromJson(int id, String title, double mrp, Map<String, dynamic> prms) {
return Product(id, title, mrp, prms);
}
}
I also recommend using json_serializable. Cause your fromJson method is not truly fromJson, but it's taking already converted Json parameters.

Dart Flutter: How to compare int values of a Map?

Say that I have a Map<String, int> containing entries and I would like to select the first entry with the highest value, see the example below:
Map<String, int> wordCount = {
'foo' : 3,
'bar' : 3,
'john' : 4,
'doe' : 3,
'four' : 4
}
What is the most efficient way to get john as it has the first highest value?
You can use something like this:
print(wordCount.entries.reduce((maxEntry, entry) {
return maxEntry.value < entry.value ? entry : maxEntry
}).key);
Something like this?
void main() {
Map<String, int> wordCount = {
'foo': 3,
'bar': 3,
'john': 4,
'doe': 3,
'four': 4
};
final nameWithHighestValue =
wordCount.entries.reduce((a, b) => a.value >= b.value ? a : b).key;
print(nameWithHighestValue); // john
}

How to transform Multimap<A,B> to Iterable<C>

How to transform Multimap<A,B> to Iterable<C> , where C(Iterable<B> iterableB)?
For example.
Iterable<String> names = ["Alice", "Anna", "Ben", "Chris", "Charlie"]
Multimap<Integer,String> namesStartWith = { [1 , ["Alice", "Anna"]], [2 , ["Ben"]], [3,["Chris", "Charlie"]] }
For each Entry<Integer , List<String>> transform to Names.
ImmutableListMultimap<Integer, String> example = Multimaps.index(newArrayList("Alice", "Anna", "Ben", "Chris", "Charlie"), new Function<String, Integer>() {
#Override
public Integer apply(String input) {
return input.startsWith("A") ? 1 : input.startsWith("B") ? 2 : 3;
}
});
List<Names> names = newArrayList();
for (Integer number : example.keys()) {
names.add(new Names(number,example.get(number)));
}
return names;
private class Names {
int startWith;
List<String> names;
public Names(int startWith, List<String> names) {
this.startWith = startWith;
this.names = names;
}
}
Is there an easier way to do this using Guava?
You can iterate over the map as follows.
for(Integer key : map.keySet()) {
for(String value : map.get(key)) {
}
}