Dart: sort list of Strings by frequency - flutter

I'm trying to sort a list by frequency.
List myList = ["a", "b", "c", "d", "e", "f", "d", "d", "e"];
My expected output would be that the list is sorted on frequency & has no duplicated elements.
(myList has 3x "d" and 2x "e").
List output = ["d", "e", "a", "b", "c", "f"];
What's the most efficient way to do it?
Thanks in advance!
Is it also possible to do the same system with a List of Maps/Objects?
List myList2 = [{"letter": a, "info": myInfo}, {"letter": b, "info": myInfo}, ...]

It is not difficult to do that even without using package:collection.
List myList = ['a', 'b', 'c', 'd', 'e', 'f', 'd', 'd', 'e'];
// Put the number of letters in a map where the letters are the keys.
final map = <String, int>{};
for (final letter in myList) {
map[letter] = map.containsKey(letter) ? map[letter] + 1 : 1;
}
// Sort the list of the map keys by the map values.
final output = map.keys.toList(growable: false);
output.sort((k1, k2) => map[k2].compareTo(map[k1]));
print(output); // [d, e, a, b, c, f]
As for the second one, your desired output is unclear, but assuming that the values corresponding to the key letter are String and that you need exactly the same output as that of the first one, you can achieve it in a very similar way.
List myList2 = [
{'letter': 'a', 'info': 'myInfo'},
{'letter': 'b', 'info': 'myInfo'},
{'letter': 'c', 'info': 'myInfo'},
{'letter': 'd', 'info': 'myInfo'},
{'letter': 'e', 'info': 'myInfo'},
{'letter': 'f', 'info': 'myInfo'},
{'letter': 'd', 'info': 'myInfo'},
{'letter': 'd', 'info': 'myInfo'},
{'letter': 'e', 'info': 'myInfo'},
];
final map2 = <String, int>{};
for (final m in myList2) {
final letter = m['letter'];
map2[letter] = map2.containsKey(letter) ? map2[letter] + 1 : 1;
}
final output2 = map2.keys.toList(growable: false);
output2.sort((k1, k2) => map2[k2].compareTo(map2[k1]));
print(output2); // [d, e, a, b, c, f]

Related

Merge value of map and insert it into another map

I have a Map <String,List> map1 that looks like that
{First: ['1', '2', '3', '4'], Second: ['A', 'B']}
I want to create another Map<String,Map<String,int>> as a ruslt of values from map1 to be like that
{'1A' : ['String1':10,'String2':20], '1B' : ['String1':10,'String2':20] , '2A' : ['String1':10,'String2':20], '2B' : ['String1':10,'String2':20], '3A' : ['String1':10,'String2':20] , '3C' : ['String1':10,'String2':20]}
I hope you get my point
Similar question Generate all combinations from multiple lists
Reference Source: https://stackoverflow.com/a/17193002/6576315
void main() async{
Map<String,List> rawMapList = {"First": ['1', '2', '3', '4'], "Second": ['A', 'B']};
List<Map<String, int>> mapResult = [{"String1" : 10}, {"String2" : 20}];
List<String> keyList = <String>[];
generatePermutations(rawMapList.values.toList(), keyList, 0, "");
var result = Map.fromEntries(keyList.map((value) => MapEntry(value, mapResult)));
print(result);
}
void generatePermutations(List<List<dynamic>> lists, List<String> result, int depth, String current) {
if (depth == lists.length) {
result.add(current);
return;
}
for (int i = 0; i < lists.elementAt(depth).length; i++) {
generatePermutations(lists, result, depth + 1, current + lists.elementAt(depth).elementAt(i));
}
}
Try first on DartPad, This code block will print
{1A: [{String1: 10}, {String2: 20}], 1B: [{String1: 10}, {String2: 20}], 2A: [{String1: 10}, {String2: 20}], 2B: [{String1: 10}, {String2: 20}], 3A: [{String1: 10}, {String2: 20}], 3B: [{String1: 10}, {String2: 20}], 4A: [{String1: 10}, {String2: 20}], 4B: [{String1: 10}, {String2: 20}]}
Do upvote reference
the solution
Map<String, dynamic> data = {
'First': ['1', '2', '3', '4'],
'Second': ['A', 'B']
};
Map<String, dynamic> ans = {};
calculate() {
for (var i in (data['First'] as List<dynamic>)) {
for (var j in (data['Second'] as List<dynamic>)) {
ans.addAll({
"$i$j": [
{'String1': 10},
{'String2': 20}
],
});
}
}
log("$ans");
}

How to copy some elements from one Map into a new Map in Dart/Flutter?

How to copy some elements from one Map into a new Map in Dart/Flutter?
Old_Map = {
'A' : {Big : 'A', Small : 'a' },
'B' : {Big : 'B', Small : 'b' },
'C' : {Big : 'C', Small : 'c' },
'D' : {Big : 'D', Small : 'd' },
}
Old_Map => New_Map
I only want
'B' : {Big : 'B', Small : 'b' },
'C' : {Big : 'C', Small : 'c' },
you can do it like this
final oldMap = {
'A': {'Big': 'A', 'Small': 'a'},
'B': {'Big': 'B', 'Small': 'b'},
'C': {'Big': 'C', 'Small': 'c'},
'D': {'Big': 'D', 'Small': 'd'},
};
final newMap =
Map.fromIterable(oldMap.keys.where((k) => k == 'B' || k =='C'),
key: (k) => k, value: (v) => oldMap[v]);
as keys returns an Iterable<String> of your map keys, then you can check which key you want by using where method, then you can fill your values based on old map values.
final List<String> desiredKeys = ['B','C'];
final newMap = Map.from(oldMap);
newMap.removeWhere((String key, dynamic value) => !desiredKeys.contains(key));
First make a List containing your desired keys. Then by using removeWhere function remove those.

python pomegranate bayesian network initialization

I have using this module to train a bayesian network.
I have this csv:
c1, c2, c3, c4 # the columns names
1, 0, 0, 1
1, 0, 1, 1
1, 1, 0, 0
0, 0, 1, 0
0, 1, 0, 0
.
.
.
I I have the edges of the network.
I know that c1 -> c3, c2->c3, c2->c4.
How can I build a bayesian network using pomegranate?
All of the documentation that i find
for example (take from the official website):
guest = DiscreteDistribution({'A': 1./3, 'B': 1./3, 'C': 1./3})
prize = DiscreteDistribution({'A': 1./3, 'B': 1./3, 'C': 1./3})
monty = ConditionalProbabilityTable(
[['A', 'A', 'A', 0.0],
['A', 'A', 'B', 0.5],
['A', 'A', 'C', 0.5],
['A', 'B', 'A', 0.0],
['A', 'B', 'B', 0.0],
['A', 'B', 'C', 1.0],
['A', 'C', 'A', 0.0],
['A', 'C', 'B', 1.0],
['A', 'C', 'C', 0.0],
['B', 'A', 'A', 0.0],
['B', 'A', 'B', 0.0],
['B', 'A', 'C', 1.0],
['B', 'B', 'A', 0.5],
['B', 'B', 'B', 0.0],
['B', 'B', 'C', 0.5],
['B', 'C', 'A', 1.0],
['B', 'C', 'B', 0.0],
['B', 'C', 'C', 0.0],
['C', 'A', 'A', 0.0],
['C', 'A', 'B', 1.0],
['C', 'A', 'C', 0.0],
['C', 'B', 'A', 1.0],
['C', 'B', 'B', 0.0],
['C', 'B', 'C', 0.0],
['C', 'C', 'A', 0.5],
['C', 'C', 'B', 0.5],
['C', 'C', 'C', 0.0]], [guest, prize])
s1 = Node(guest, name="guest")
s2 = Node(prize, name="prize")
s3 = Node(monty, name="monty")
model = BayesianNetwork("Monty Hall Problem")
model.add_states(s1, s2, s3)
model.add_edge(s1, s3)
model.add_edge(s2, s3)
model.bake()
There is no way to build a state if the probabilities are unknown
how can /i do that?

mongo find multiple array pairs

If I have an array of pairs like so:
[
{foo: 'a', bar: 'b'},
{foo: 'b', bar: 'c'},
{foo: 'a', bar: 'd'},
{foo: 'b', bar: 'b'},
]
And I want to find documents in a collection that match any of these pairs exactly, how do I do this?
I've looked at the $in, $all, $elemMatch operators but none of them seem to quite do what I want.
I could do the queries individually:
db.baz.find({foo: 'a', bar: 'b'})
db.baz.find({foo: 'b', bar: 'c'})
db.baz.find({foo: 'a', bar: 'd'})
db.baz.find({foo: 'b', bar: 'b'})
But what I'd like to do is something like this:
db.baz.find([
{foo: 'a', bar: 'b'},
{foo: 'b', bar: 'c'},
{foo: 'a', bar: 'd'},
{foo: 'b', bar: 'b'},
]);
Try the $or syntax:
db.baz.find({
$or: [
{ foo: 'a', bar: 'b' },
{ foo: 'b', bar: 'c' },
{ foo: 'a', bar: 'd' },
{ foo: 'b', bar: 'b' },
]
})

GroupBy and CountBy for multiple values

I am trying to use underscorejs to groupBy multiple values based on below data.
var obj = [
{
'Name': 'A',
'Status': 'Ticket Closed'
},{
'Name': 'B',
'Status': 'Ticket Open To Close'
},{
'Name': 'A',
'Status': 'Ticket Closed'
},{
'Name': 'B',
'Status': 'Ticket Open'
},{
'Name': 'A',
'Status': 'Ticket Open To Closed'
},{
'Name': 'A',
'Status': 'Ticket Open'
},{
'Name': 'B',
'Status': 'Ticket Open'
}
];
The expected output is
[{
'Name': Closed',
'Count': [2, 0]
},{
'Name': Open',
'Count': [2, 3]
}]
First object counts all closed tickets (Where the status contains the word closed) for A and B simultaneously. Similarly the second object counts for Open tickets. Here is what I tried
var arr = _.groupBy(obj, function (row) {
return (row["Status"].indexOf('Open') > 0 ? "Open" : "Closed");
});
var arr1 = _.groupBy(arr["Closed"], 'Name');
var arr2 = _.groupBy(arr["Open"], 'Name');
var cData = [];
cData.push(arr1);
cData.push(arr2);
Unable to get count from same code. Any help?
Ok. So I was able to resolve this. Here's the working example
http://jsfiddle.net/7ETKV/
Here is the solved code:
var jsondata = jsondata.sort(function (a, b) {
return a.Name.localeCompare(b.Name);
});
_.each(jsondata, function (row, idx) {
((row.Status.indexOf('Open') > 0) ? jsondata[idx].bgStatus = 'Open' : jsondata[idx].bgStatus = 'Closed');
});
var cdata = [], xobj = {};
var gd = _.groupBy(jsondata, 'bgStatus');
var cats = _.keys(_.groupBy(jsondata, 'Name'));
for (var p in gd) {
var arr = _.countBy(gd[p], function (row) {
return row.Name;
});
_.each(cats, function (row) {
if (!arr.hasOwnProperty(row)) arr[row] = 0;
});
xobj.Name = p;
xobj.Data = _.values(arr);
cdata.push(xobj);
xobj = {};
}
Hope might help someone. Any updates to the code / optimizations are welcome.