Dart: I want to check if the contents of 2 Lists are the same - flutter

One List is a List<String>? and the other is a List<dynamic>
I'd prefer not to change these data types. I just want to check if the contents are the same.
If I have a List [1, 2, 3] and a List [1, 2, 3] the output of a bool should be true
If I have a List [1, 2, 3] and a List [1, 3, 2] the output of a bool should be true
If I have a List [1, 2, 4] and a List [1, 2, 3] the output of a bool should be false

I will sort in this case and check equal like
final e1 = [1, 2, 3]..sort();
final e2 = [1, 3, 2]..sort();
print(e1.equals(e2)); //true

void main() {
List<int> a = [1, 2, 3];
List<dynamic> b = [1, 3, 3];
bool checkSame(List<dynamic> a, List<dynamic> b) {
var same = true;
if (a.length != b.length) {
same = false;
} else {
a.forEach((element) {
if (element.toString() != b[a.indexOf(element)].toString()) {
same = false;
}
});
}
return same;
}
bool val = checkSame(a, b);
print(val);
}

I recommend to use collection package with 564 like on pub.dev. to compare lists/maps/sets
i found from here https://stackoverflow.com/a/63633370/12838877
To compare list of integer and list of dynamic
import 'package:collection/collection.dart';
List<int> a = [1,2,4,5,6];
List<dynamic> b = [1,2,4,5,6];
List<dynamic> c = [1,4,5,6,2];
bool isEqual = DeepCollectionEquality().equals(a,b);
bool isEqual2 = DeepCollectionEquality().equals(a,c);
print(isEqual); // result is true without any error
print (isEqual2); // result is false , since its not ordered
UPDATE
if you want to compare 2 list dynamic unordered you can use code below
final unOrderedList = DeepCollectionEquality.unordered().equals(a,c);
print(unOrderedList); // result true
since its dynamic list, its also can compare between list that contain int,null, string ,list , etc,
List<dynamic> d = [1,"abc",2, null, ["a"], 4];
List<dynamic> e = [1,"abc",2, null, ["a"], 4];
final compare2list = DeepCollectionEquality.unordered().equals(d,e);
print(compare2list); // result true

Related

why is the If statement is not working even if the condition is true? dart & flutter [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
why is the If (isNormal == true) statement is not working even if the condition is true
the code that I tried to do are as below
_checkResult() {
bool isNormal = false;
isNormal = userAnswer.every((item) => normalList.contains(item));
if (isNormal) {
print("Normal");
} else {
print("Try Again");
}
}
I already tried to print both lists to check if both data are the same or not,
Both lists and result of if condition
As you can see, both list are the same, but the result does not change. Please help
You can follow any of this
bool withEvery(List<int> mainItems, List<int> subItems) {
final result = subItems.every((element) => mainItems.contains(element));
return result;
}
or
bool containsItem(List<int> mainItems, List<int> subItems) {
for (final i in subItems) {
if (!mainItems.contains(i)) {
return false;
}
}
return true;
}
to get desire result.
test case
test("containsItem n check", () {
final normalList = [1, 3, 2];
final userAnswer = [1, 2, 3];
final userAnswer1 = [2, 1, 3];
final userAnswer2 = [2, 1, 0];
final result = containsItem(normalList, userAnswer);
expect(result, true);
final result1 = containsItem(normalList, userAnswer1);
expect(result1, true);
final result2 = containsItem(normalList, userAnswer2);
expect(result2, false);
});
test("withEvery ", () {
final normalList = [1, 3, 2];
final userAnswer = [1, 2, 3];
final userAnswer1 = [2, 1, 3];
final userAnswer2 = [2, 1, 0];
final result = withEvery(normalList, userAnswer);
expect(result, true);
final result1 = withEvery(normalList, userAnswer1);
expect(result1, true);
final result2 = withEvery(normalList, userAnswer2);
expect(result2, false);
});
And your methods also working fine
I am not sure I understand the question but
I assume you are trying to print 'Normal' when the list contents are same.
If so, then your if condition should be like this
if(isNormal){ print('Normal'); }
meaning you have to just put the bool variable as is, but you have used the Not (!) operator with it so its giving you the opposite result.

How can I get the name of the list that I set myself?

I have a raw list like this:
var listRaw = [
{
"listName": "listA",
"listValue": [1, 2, 3]
},
{
"listName": "listB",
"listValue": [4, 5, 6]
},
{
"listName": "listC",
"listValue": [7, 8, 9]
}
];
and empty lists like this:
List<int> listA = [];
List<int> listB = [];
List<int> listD = [];
List<List<int>> listFilled = [listA, listB, listD];
How can I get the names of empty lists as a condition to add listVaule in listRaw to them if name of empty list == listName? => then listFilled will have the result [[1,2,3], [4,5,6], []]
So pls help me, this is my code so far
void main() {
var listRaw = [
{
"listName": "listA",
"listValue": [1, 2, 3]
},
{
"listName": "listB",
"listValue": [4, 5, 6]
},
{
"listName": "listC",
"listValue": [7, 8, 9]
}
];
List<int> listA = [];
List<int> listB = [];
List<int> listD = [];
List<List<int>> listFilled = [listA, listB, listD];
listRaw.forEach((r) {
listFilled.forEach((f) {
if (r['listName'] == ___ ) { // How to get name of (f)
f.addAll(r['listValue']);
}
});
});
print(listFilled); // want result: [[1,2,3], [4,5,6], []]
}
The variable names that you use are for you to understand what the variable is being used for. The compiler does not know what you named them. It only knows that this variable is pointing towards a specific point of memory.
That being said, what you can do is create your own subclass of the List class which will have a name attached to it. In that way, you can check the name of the List when you want to compare it. Your subclass should be something like this
This is not exact syntax. Just an overview of what needs to be done.
class MyNamedList extends List {
String name;
MyNamedList(String name) {
this.name = name;
}
}
//You can check for name like this
if (r['listName'] == myNamedListObj.name)
var listRaw = [
{
"listName": "listA",
"listValue": [1, 2, 3]
},
{
"listName": "listB",
"listValue": [4, 5, 6]
},
{
"listName": "listC",
"listValue": [7, 8, 9]
}
];
this is a List of Map<String, dynamic>
so what you need to do is create empty List<Map<String,dynamic>>
List<Map<String,dynamic>> list = List.empty(growable:true);//set false if size is fixed.
Then List<List<Map<String,dynamic>>> listFilled = [list1,list2,list3];

how to access a class's object by its name which is stored in a String?

I would like to select an object in a class by its name stored in a variable. Is this feasible? So basically a syntax for the placeholder -magic_syntax- or any other method how this can be achieved.
const String kListNames = {'list1', 'list2'};
class MyClass {
List<int> list1 = [0, 1, 2];
List<bool> list2 = [true, false];
}
main() {
List<dynamic> myList;
MyClass myClass;
for (var listName in kListNames) {
myList = myClass.-magic_syntax-(listName);
}
}
Dart is a Compile time language. It's not possible to interact with variables through their variable names in the way you're suggesting.
why not store your data in a Map?
Map<String, List> myData = {
'list1': [0, 1, 2],
'list2': [true, false],
}:
for(final listName in myData.keys) {
...
}
now you can loop over the data keys myData.keys, the values myData.values or both myData.entries

How to remove a certain number of duplicates from a list

I want to delete a certain number of duplicates from an ordered list in Dart. It could also be taken as the deletion of duplicates after a certain number of occurrences.
To illustrate my question, I will give an example, which could explain the problem much better than my words:
I want to keep 3 duplicates max. of each number or category.
This is what I am given:
[1,1,1,1,2,2,2,2,3,4,4,5,5,5,5,5]
Notice the occurrences per number. 3 and 4 are only present in the array one and two times correspondingly.
This is what I want that list to become:
[1,1,1,2,2,2,3,4,4,5,5,5]
void main(List<String> args) {
var numbers = [1,1,1,1,2,2,2,2,3,4,4,5,5,5,5,5];
const max_duplicates = 3;
var base = numbers.toSet();
var result = <int>[];
base.forEach((number) {
var counter = numbers.where((e) => e == number).length;
result.addAll(List.filled(counter > max_duplicates ? max_duplicates : counter, number));
});
print(result);
}
Result:
[1, 1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5]
var toRemove = [];
var localScore = 10;
var cuentaLocal = 0;
filteredCareTakers.forEach((item) {
if (localScore > item['score']) {
localScore = item['score'];
cuentaLocal = 0;
} else if (localScore == item['score']) {
if (cuentaLocal == 2) {
toRemove.add(item);
} else {
cuentaLocal++;
}
}
});
filteredCareTakers.removeWhere((element) => toRemove.contains(element));
void main() {
final input = [1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 4, 5, 5, 5, 5, 5];
final seen = <Object, int>{};
var output = <Object>[];
for (var e in input) {
seen[e] = (seen[e] ?? 0) + 1;
if (seen[e]! <= 3) output.add(e);
}
print(output);
}
or for the functional programmers:
void main() {
final input = [1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 4, 5, 5, 5, 5, 5];
final count = <Object, num>{};
final output = input.where((e) {
count[e] = (count[e] ?? 0) + 1;
return count[e]! <= 3;
}).toList();
print(output);
}
I imagine you could do something with .fold and and a tuple, but that just seems like too much work. :)

Get most popular value in a list

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.