I have a list of items containing unique and repeating IDs, I want to sum the prices and display the number of the repeating IDs
class Model{
int id,price,count;
Model(this.id,this.price,this.count);
}
List<Model> list1 = [
Model(1,5000,10),
Model(2,1000,20),
Model(1,5000,5),
Model(2,5000,10),
];
List<Model> list2 = [];
I need the second list to be like this
list2 = [
Model(1,10000,15),
Model(2,6000,30),
];
try this :
void main() {
int sum = 0;
List<Model> list1 = [
Model(1, 5000, 10),
Model(2, 1000, 20),
Model(1, 5000, 5),
Model(2, 5000, 10),
];
List<Model> list2 = modelsWithoutRepeatingIdsButSumOfPricesAndAmount(
list1); // [Model(1,10000,15), Model(2,6000,30),]
}
List<Model> modelsWithoutRepeatingIdsButSumOfPricesAndAmount(
List<Model> modelList) {
Map<int, Model> map = {};
for (int index = 0; index < modelList.length; index += 1) {
Model current = modelList[index];
map[current.id] ??= Model(current.id, 0, 0);
map[current.id]!.price += current.price;
map[current.id]!.count += current.count;
}
return map.values.toList();
}
class Model {
int id, price, count;
Model(this.id, this.price, this.count);
}
Use reduce method to get the sum of a list
var total = [1, 2, 3].reduce((a, b) => a + b);
If you don't want to use reduce method you can also use .fold() there are couple more you can get them by importing dart collections package.
Related
Random 3 Element with repeating
How to random select 3 element without repeating?
List<Question> imageList = [
Question(
index: 1,
image: 'assets/images/1.png',
),
Question(
index: 2,
image: 'assets/images/2.png',
),
Question(
index: 3,
image: 'assets/images/3.png',
),
Question(
index: 4,
image: 'assets/images/4.png',
),
Question(
index: 5,
image: 'assets/images/5.png',
),
];
This is Element List
getRandom =
List<Question>.generate(3, (_) => imageList[random.nextInt(imageList.length)]);
This is Random Function with repeating.
You could define an extension on List<T> so you can reuse it on all types of List:
List<String> alphabets = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
extension XList<T> on List<T> {
List<T> takeRandom(int n) {
return ([...this]..shuffle()).take(n).toList();
}
}
void main() {
print(alphabets.takeRandom(3));
print(alphabets.takeRandom(5));
print(alphabets.takeRandom(7));
}
Console log
[B, S, G]
[P, M, F, Q, K]
[U, M, R, C, Z, D, G]
Get the list count;
int total = imageList.length;
create index list numbers;
var listindex = List<int>.generate(total, (i) => i++);
shuffle list;
listindex .shuffle();
//result
[3, 6, 2, 0, 9, 1, 5, 7, 8, 4]
and get data from first 3 index list.
imageList[3].image
imageList[6].image
imageList[2].image
I solved this problem
Initialized with variable
List<Question> getRandom = [];
late Question correctElement;
Random random = Random();
Init State for first time run
#override
void initState() {
setRandom();
if (kDebugMode) {
print('getRandomNum is $getRandom & correctElement is $correctElement');
}
super.initState();
}
Used do while loop to unrepeate
Question shaffel() {
return imageList[random.nextInt(imageList.length)];
}
setRandom() {
getRandom.clear();
do {
Question data = shaffel();
if (getRandom.isEmpty) {
setState(() {
getRandom.add(data);
});
} else if (getRandom.contains(data)) {
} else {
setState(() {
getRandom.add(data);
});
}
} while (getRandom.length != 3);
correctElement = getRandom[random.nextInt(getRandom.length)];
}
After a few days it didn't work, I combined the data on the model initially
example: Samsung has a lot of data and I have combined it into an array, I want to ask how to make a search based on the brand name of the model?
#override
Widget build(BuildContext context) {
remoteModelId.clear();
isLoading = true;
final products = Provider.of<List<Brands>>(context);
return Scaffold(
...
body: products != null
? ListView.separated(
itemCount: products.length,
itemBuilder: (context, index) {
var lol = [];
var idModel = [];
var sublist = [].join();
var countList =[];
//var allList =[];
//var subLol = lol.indexOf(lol);
for(var ok in products){
lol.add(ok.brandName);
idModel.add(ok.ids);
countList.add(lol);
if(lol.contains(lol)){
sublist.compareTo(lol[index]);
break;
}
}
distinctIds = lol.toSet().toList();
hasilakhir = Set.of(distinctIds).toList();
newDataList = List.from(distinctIds);
templist.add(hasilakhir);
final myMap = Map();
lol.forEach((element) {
if(!myMap.containsKey(element)){
myMap[element] = 1;
return false;
}else{
myMap[element] += 1;
return false;
}
});
//newDataList = newDataList.map((brand)=>brand.toLowerCase()).toList();
return ListTile(
title: Text(hasilakhir[index]),
Thanks
I am not sure what you need, but here is some example code:
// Get products with a specific brandName
print(
'Number of Samsung=${products.where((p) => p.brandName == 'Samsung').length}');
// Count products by brandName - like your code
final map = Map();
products.forEach((product) {
if (!map.containsKey(product.brandName)) {
map[product.brandName] = 1;
} else {
map[product.brandName] += 1;
}
});
print('map=$map');
// Group products by brandName, with the count and list of ids
final map2 = Map();
products.forEach((product) {
if (!map2.containsKey(product.brandName)) {
map2[product.brandName] = {
'count': 1,
'ids': [product.ids]
};
} else {
var current = map2[product.brandName];
current['count']++;
current['ids'].add(product.ids);
}
});
print('map2=$map2');
The output with my test data is:
Number of Samsung=3
map={Samsung: 3, Apple: 3}
map2={Samsung: {count: 3, ids: [S1, S2, S3]}, Apple: {count: 3, ids: [iPhone1, iPhone2, iPhone3]}}
I do not know if it is helpful, but I have annotated some of your code below:
// Get list of distinct brandNames
var distinctIds = lol.toSet().toList();
// Get list of distinct brandNames - same as distinctIds
var hasilakhir = Set.of(distinctIds).toList();
// Copy list distinctIds
var newDataList = List.from(distinctIds);
List templist = [];
// Make a list with one element which is the list of brandNames
templist.add(hasilakhir);
I have a list
final List list = [1, 2, 3, 4, 5, 6, 7];
how can I "map" to the output as a new List like:
"1 and 2",
"3 and 4",
"5 and 6",
"7"
You can achieve that using the following function:
_getComponents(list) => list.isEmpty ? list :
([list
.take(2)
.join(' and ')
]..addAll(_getComponents(list.skip(2))));
Call that function like:
List outPut = _getComponents(yourList);
Explanation:
You are declaring a recursive function called _getComponents
As the first statement you are checking whether the parameter list is empty, if it's empty returning the parameter as is
If the list is not empty
You are taking the first 2 items from the list using take function
You are joining those elements using join function
You are calling the addAll function and supplies the result of recursive _getComponents call as it's argument
And as the parameter of that _getComponents function you are passing the list, after skipping the first 2 elements using the skip function
Answer came off the top of my head but try this:
final List list = [1, 2, 3, 4, 5, 6, 7];
List<String> grouped = [];
for (int i = 0; i < list.length; i++) {
if (i % 2 == 0) {
if (i + 1 < list.length) {
grouped.add("${list[i]} and ${list[i + 1]}");
} else {
grouped.add("${list[i]}");
break;
}
}
}
print(grouped);
This works
main(){
final List list = [1,2,3,4,5,6,7];
final List newList = [];
for(int i = 0; i<list.length; i++){
var string;
if(i+1<list.length){
string = "${list[i]} and ${list[i+1]}";
i++;
}else{
string = "${list[i]}";
}
newList.add(string);
}
print(newList);
}
Write this:
void main(){
final List oldList = [1,2,3,4,5,6,7];
final List newList = [];
for(int i = 0; i<list.length; i += 2){
if(i+1<oldList.length){
newList.add("${oldList[i]} and ${oldList[i+1]}");
}else{
newList.add("${oldList[i]}");
}
}
print(newList);
}
How I can get the most popular number from a list in dart without using any third party libraries?
var list = [0, 1, 1, 2, 2, 2, 3, 3, 4]; // most popular number is 2
If there are two or more popular numbers then the output should be a List with both values. Example:
One popular number:
var list = [0, 1, 1, 2, 2, 2, 3, 3, 4];
// Output should be [2]
Two or more popular numbers:
var list = [0, 1, 1, 2, 2, 2, 3, 3, 3];
// Output should be [2, 3]
Thank you in advance for your help!
This works...you can optimize it
var list = [1, 1, 2, 2, 3, 4, 5];
list.sort();
var popularNumbers = [];
List<Map<dynamic, dynamic>> data = [];
var maxOccurrence = 0;
var i = 0;
while (i < list.length) {
var number = list[i];
var occurrence = 1;
for (int j = 0; j < list.length; j++) {
if (j == i) {
continue;
}
else if (number == list[j]) {
occurrence++;
}
}
list.removeWhere((it) => it == number);
data.add({number: occurrence});
if (maxOccurrence < occurrence) {
maxOccurrence = occurrence;
}
}
data.forEach((map) {
if (map[map.keys.toList()[0]] == maxOccurrence) {
popularNumbers.add(map.keys.toList()[0]);
}
});
print(popularNumbers);
try this to count each element in list:
var list = [0, 1, 1, 2, 2, 2, 3, 3, 4];
var popular = Map();
list.forEach((l) {
if(!popular.containsKey(l)) {
popular[l] = 1;
} else {
popular[l] +=1;
}
});
I guess I found the solution.
Let me explain it to you:
I had queried through your list and checked whether the keys of the map contains the element or not. If the map does not contain the element as the key then, it will create a key from the element and pass 1 as the value. If the map does contain the element as a key then it will simply increment the value.
Once the map is ready, I had sorted the map values and stored them in a List. From the sorted map values I had taken the last element from the list of sorted values because we had sorted it in ascending order so the most popular value will be at last.
At last, I had queried through the map and check whether the value of the particular key is equal to the popularValue or not. If it is then we are adding the current key and value to the mostPopularValues list.
If I got something wrong please let me know.
void main() {
List list = [0, 1, 1, 1, 2, 2, 2, 3, 3, 4];
List mostPopularValues = [];
var map = Map();
list.forEach((element) {
if (!map.containsKey(element)) {
map[element] = 1;
} else {
map[element] += 1;
}
});
print(map);
// o/p : {0: 1, 1: 3, 2: 3, 3: 2, 4: 1}
List sortedValues = map.values.toList()..sort();
print(sortedValues);
// o/p : [1, 1, 2, 3, 3]
int popularValue = sortedValues.last;
print(popularValue);
// o/p : 3
map.forEach((k, v) {
if (v == popularValue) {
mostPopularValues.add("$k occurs $v time in the list");
}
});
print(mostPopularValues);
// o/p : [1 occurs 3 time in the list, 2 occurs 3 time in the list]
}
Not sure if that's the best solution, but it works pretty well. Let me know if there are any doubts.
final list = [0, 1, 1, 2, 2, 2, 3, 3, 4];
// Count occurrences of each item
final folded = list.fold({}, (acc, curr) {
acc[curr] = (acc[curr] ?? 0) + 1;
return acc;
}) as Map<dynamic, dynamic>;
// Sort the keys (your values) by its occurrences
final sortedKeys = folded.keys
.toList()
..sort((a, b) => folded[b].compareTo(folded[a]));
print('Most popular value: ${sortedKeys.first}'); // 1
print('Second most popular value: ${sortedKeys[1]}'); // 2
I have solved this problem by defining an extension on Iterable:
extension MostPopularItemsExtension<E> on Iterable<E> {
/// Returns the most popular items, where all items in the returned
/// list have the same number of occurances. If [this] is empty, returns an
/// empty list
///
/// Examples:
/// `[1,2,3,2].mostPopularItems() == [2]`
/// `[1,1,2,2].mostPopularItems() == [1,2]`
Iterable<E> mostPopularItems() {
if (isEmpty) return [];
final itemsCounted = <E, int>{};
for (final e in this) {
if (itemsCounted.containsKey(e)) {
itemsCounted[e] = itemsCounted[e]! + 1;
} else {
itemsCounted[e] = 1;
}
}
final highestCount = (itemsCounted.values.toList()..sort()).last;
return itemsCounted.entries
.where((e) => e.value == highestCount)
.map((e) => e.key);
}
}
The basic idea is to count all occurrences of each item in a Map object, get the highest count from this map and then return all items that have that specific number of occurrences.
I found online soluton like this:
import 'package:queries/collections.dart';
void main() {
List<String> list = ["a", "a", "b", "c", "b", "d"];
var result = new Collection(list).distinct();
print(result.toList());
}
But, I don't know how to convert var result back to List<Widget>.
There is a way that is a lot easier and does not require any additional imports.
You can convert your List to a Set which inherently only contains distinct elements and then convert that Set back to a List.
If you are using Dart 2.3 or higher (environment: sdk: ">=2.3.0 <3.0.0"), you can use the following idiomatic version:
List<String> list = ['a', 'a', 'b', 'c', 'b', 'd'];
List result = [...{...list}];
The ... spread operator for iterables was just introduced with Dart 2.3.
Otherwise, you can just use old syntax:
List<String> list = ["a", "a", "b", "c", "b", "d"];
List result = list.toSet().toList();
Thank you for your answer,
Here is the full code, i try to modify your method but not working.
(Works only in print)
Future<List<List<Widget>>> getList(List<int> list, String column) async {
List<Widget> list1 = List();
List<Widget> list2 = List();
List<Widget> list3 = List();
//test
List<String> testlista = List();
testlista.add(result[0][column].toString());
List<List<Widget>> listFromDB = [list1, list2, list3];
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'books.db');
Database database = await openDatabase(path, version: 1);
for (int i = 0; i < list.length; i++) {
var result = await database.rawQuery(
'SELECT DISTINCT $column FROM planner WHERE id = ${list[i]}');
//here polulate new List
testlista.add(result[0][column].toString());
if (list[i] < 18) list1.add(_item(result[0][column].toString()));
if (list[i] > 17 && list[i] < 50)
list2.add(_item(result[0][column].toString()));
if (list[i] > 49) list3.add(_item(result[0][column].toString()));
}
//Now this give me corect print list without duplicate!!!
for (int i = 0; i < testlista.length-1; i++) {
print('FROM DELETE method: '+ deleteDuplicate(testlista)[i]);
}
await database.close();
return listFromDB;
}
//Method for removingDuplicate
List<String> deleteDuplicate(List<String> lista) {
// List<String> result = Set.from(lista).toList();
List<String> result = {...lista}.toList();
return result;
}