How to count items' occurence in a List - list

I am new to Dart. Currently I have a List of duplicate items, and I would like to count the occurence of them and store it in a Map.
var elements = ["a", "b", "c", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e", "a"];
I want to have a result like:
{
"a": 3,
"b": 2,
"c": 2,
"d": 2,
"e": 2,
"f": 1,
"g": 1,
"h": 3
}
I did some research and found a JavaScript solution, but I don't know how to translate it to Dart.
var counts = {};
your_array.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });

Play around with this:
var elements = ["a", "b", "c", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e"];
var map = Map();
elements.forEach((element) {
if(!map.containsKey(element)) {
map[element] = 1;
} else {
map[element] += 1;
}
});
print(map);
What this does is:
loops through list elements
if your map does not have list element set as a key, then creates that element with a value of 1
else, if element already exists, then adds 1 to the existing key value
Or if you like syntactic sugar and one liners try this one:
var elements = ["a", "b", "c", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e"];
var map = Map();
elements.forEach((x) => map[x] = !map.containsKey(x) ? (1) : (map[x] + 1));
print(map);
There are many ways to achieve this in all programming languages!

The shorter way to count items' occurrence in a List
List of items. Count items equal 1.
List<int> lst = [0,1,1,1,0,8,8,9,1,0];
int res = lst.map((element) => element == 1 ? 1 : 0).reduce((value, element) => value + element);
List of objects. Count objects, which property age equals 1.
class Person {
int age;
Person(this.age);
}
List<Person> lst2 = [Person(1), Person(0), Person(1), Person(0)];
int res2 = lst2.map((element) => element.age == 1 ? 1 : 0).reduce((value, element) => value + element);

Use fold with a map:
final elements = ["a", "b", "c", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e", "a"];
var counts = elements.fold<Map<String, int>>({}, (map, element) {
map[element] = (map[element] ?? 0) + 1;
return map;
});
print(counts);
Out: {a: 3, b: 2, c: 2, d: 1, e: 2, f: 1, g: 1, h: 3}

Related

Filtering ArrayField by entire and exact array only?

I have a slug ArrayField on a model.
How can I filter or get by the entire exact array only?
I'm currently doing something like this:
search = f'["a", "b", "c"]'
list = search[2:-2].split("', '")
dict = {}
for n, item in enumerate(list):
dict[f"slug__{n}"] = item
obj = queryset.filter(**dict)
However, this returns any object where the slug begins with "a", "b", and "c".
E.g.
["a", "b", "c"]
["a", "b", "c", "d"]
["a", "b", "c", "d", "e"]
["a", "b", "c", "123"]
How do I do a filter or get so that only the entire and exact slug match returns? I.e. obj only returns objects with a slug of ["a", "b", "c"]
To filter an ArrayField by an exact match you can just pass the list to match against to a filter
queryset = queryset.filter(slug=["a", "b", "c"])

Printing the most frequent value in a text

Let's say I have a list of string.
I saw the code on: How to count items' occurence in a List
I want to print the most frequent string as a text in my widget. How do i run this and print it in there?
Do i go by void main() ?
class user with ChangeNotifier {
static String topWord;
notifyListeners();
}
void countWord() {
var elements = ["a", "b", "c", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e"];
var popular = Map();
elements.forEach((element) {
if(!popular.containsKey(element)) {
popular[element] = 1;
} else {
popular[element] +=1;
}
});
print(popular);
return user.topWord = popular;
}
Attached are some screenshots when I return the results
Here you can first create the map of your counted values and then using that map you can get the maximum value of the key.
Source Here
class HomePage extends StatelessWidget {
String email;
var maxocc = maxOccurance();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("App Bar"),
),
body: Center(
child: Container(
child: Text(maxocc),
),
),
);
}
}
String maxOccurance() {
var elements = [
"a",
"b",
"c",
"d",
"e",
"a",
"b",
"c",
"f",
"g",
"h",
"h",
"h",
"e"
];
// Here creating map of all values and counting it
final folded = elements.fold({}, (acc, curr) {
acc[curr] = (acc[curr] ?? 0) + 1;
return acc;
}) as Map<dynamic, dynamic>;
print(folded);
// Here getting maximum value inside map
final sortedKeys = folded.keys.toList()
..sort((a, b) => folded[b].compareTo(folded[a]));
return "${sortedKeys.first} occurs maximun times i.e. ${folded[sortedKeys.first]}";
}
Output Here

AppSync Subscription Filters

We need a way to filter a subscription in the following manner:
type Subscription {
onPlanningViewUpdate(prop1: ["a", "b", "c"]): ReturnObject
}
ReturnObject = {prop1: "a", ...} // would pass through
ReturnObject = {prop1: "b", ...} // would pass through
ReturnObject = {prop1: "c", ...} // would pass through
ReturnObject = {prop1: "x", ...} // would NOT pass through
We have tried using the request and response mapping templates of a resolver with a NONE type data source, but the mappings seem to only get called once when the subscription is first opened. It looks like subscriptions only handle an exact match. We need a way to determine if a prop is contained in the array ["a", "b", "c"]. If prop1 == "a" or prop1 == "b" or prop1 == "c" pass through.
Here is the actual filter we want to use:
type Subscription {
onPlanningViewUpdate(site_ids: ["a", "b", "c"], planDate: "aString", lob_ids: ["x", "y", "z"]):
ReturnObject
}
ReturnObject = {site_ids: "a", planDate: "aString", lob_ids: "y"} // would pass through
ReturnObject = {site_ids: "a", planDate: "wrongString", lob_ids: "y"} // would NOT pass through
Is there a way to do this ?
Thanks,
Warren Bell

rapidjson cocos2d-x parsing

rapidjson::Document d;
d.Parse<0>(chatevent.chat.c_str());
if(d.HasMember("kelimeler"))
{
rapidjson::Value::MemberIterator M;
const char *key,*value;
for (M=d.MemberBegin(); M!=d.MemberEnd(); M++)
{
key = M->name.GetString();
value = M->value.GetString();
if (key!=NULL && value!=NULL)
{
log("key: %s, value: %s", key,value);
}
}
}
This is the code i use to handle json data in cocos2d-x. And here is the json:
{
"kelimeler": [{
"harfsayisi": 10,
"kelime": "bibnştvdaf",
"harfler": ["t", "s", "ç", "p", "b", "c", "h", "n", "c", "c", "n", "b", "t", "v", "ş", "v", "a", "c", "v", "p", "d", "ğ", "s", "k", "i", "ç", "f", "v", "b", "p", "a", "ü", "d", "ü", "e"]
}]
}
So how to handle it using the code? I simply can not get the "kelimeler" branch. Thanks in advance.
Need to remember to watch out for namespace collisions. Ideally the compiler warns about ambiguity. In your case you need to specify you want the classes from rapidjson and not cocos2d.
Updating Josh's example.
rapidjson::Document d;
d.Parse<0>(chatevent.chat.c_str());
if(d.HasMember("kelimeler"))
{
const rapidjson::Value& k = d["kelimeler"]; // you are missing this
assert(k.IsArray());
if(k.HasMember("harfler"))
{
const rapidjson::Value& h = k["harfler"];
for (rapidjson::SizeType i = 0; i < h.Size(); i++)
{
log("value: %s", h[i].GetString());
}
}
}
No where in you're code does it actually get the "kelimeler" array. See the rapidjson tutorial http://rapidjson.org/md_doc_tutorial.html#ValueDocument
if(d.HasMember("kelimeler"))
{
const Value& k = d["kelimeler"]; // you are missing this
assert(k.IsArray());
for (SizeType i = 0; i < k.Size(); i++)
{
...
}
}

How to collate list items with the same first item onto a map

I know this is probably a very simple List operation in Scala, but I'm a newbie and can't figure it out. I have a query that returns a result set with a series of values, grouped by a common id. For example:
Result Set:
[{ 1, "a", 30 },
{ 1, "b", 20 },
{ 1, "c", 22 },
{ 2, "a", 32 },
{ 2, "c", 10 }]
and what I'd like to do is put this into a map as such:
1 -> [{"a", 30}, {"b", 20}, {"c", 22}]
2 -> [{"a", 32}, {"c", 10}]
I think the collect method can be used for this but can't figure it out.
I'm not sure what the types in your data structure are, but maybe you can adapt this. This assumes you have a collection of tuples:
val items =
List((1, "a", 30),
(1, "b", 20),
(1, "c", 22),
(2, "a", 32),
(2, "c", 10))
items
.groupBy{ case (a,b,c) => a }
.mapValues(_.map{ case (a,b,c) => (b,c) })
// Map(1 -> List((a,30), (b,20), (c,22)), 2 -> List((a,32), (c,10)))
Or, more succinctly:
items.groupBy(_._1).mapValues(_.map(t => (t._2, t._3)))
The collect method is something else entirely (basically, it's map that drops non-matching values). The groupBy method is what you were really looking for.