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
Related
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}
I have a list of items (actually an IEnumerable). Each item has a list of values. For example:
Item1.Value[0] = "Health & Safety"
Item1.Value[1] = "Economic"
Item1.Value[2] = "Environment"
Item2.Value[0] = "Reputation"
Item2.Value[1] = "Environment"
Item2.Value[2] = "Regulatory"
...
How can I order the list of values using linq? I know I can order the list of items using something like:
Items.Orderby(x => x.something)
...but how do I get to the list of values in each item?
You can try this
Items.ForEach(i=> x.something = x.something.OrderBy(o=> o.field));
EDIT: Based off OP's comment, Value is a Dictionary<string, object>. You cannot sort a Dictionary as they are unordered by design.
Consider using a SortedDictionary<TKey, TValue>, and implement an IComparer<TKey> to fit your sorting needs:
Example:
Dictionary<string, object> values = new Dictionary<string, object>
{
{ "b", 1 }, { "a", 2 }, { "c", 3 }
};
// { { "a", 2 }, { "b", 1 }, { "c", 3 } }
SortedDictionary<string, object> keyAscending =
new SortedDictionary<string, object>(values);
public class ReverseStringComparer : IComparer<string>
{
int IComparer<string>.Compare(string x, string y)
{
return y.CompareTo(x);
}
}
// { { "c", 3 }, { "b", 1 }, { "a", 2 } }
SortedDictionary<string, object> keyDescending =
new SortedDictionary<string, object>(values, new ReverseStringComparer());
I'm new in swift. I'm trying to add an Array to a specific key in my Dictionary.
I have the following code:
var myArray : Array<Links> = []
var myDict : Dictionary<String, AnyObject> = [:]
myDict["links"] = myArray as AnyObject? // I need help in this row, It does not work.
This is the Json structure I have in myDict and I'm trying to set:
id : "blabla"
links: [
0: {key1: "a", key2: "b", name: "c", link: "d"}
1: {key1: "e", key2: "f", name: "j", link: "h"}
]
Please, consider I already have all the rest working properly. My only problem is how to add my array in the dictionary as commented in the code above.
My JSON structure:
I hope I could make myself clear enough.
Thank you.
First of all don't cast types up and don't annotate types unless the compiler complains.
Second of all a JSON dictionary is [String:Any] in Swift 3.
Further the recommended syntax to create an empty collection object is
var myDict = Dictionary<String, Any>()
Assuming your array – actually a dictionary – is
let myArray = [
0: ["key1": "a", "key2": "b", "name": "c", "link": "d"],
1: ["key1": "e", "key2": "f", "name": "j", "link": "h"]
]
just assign it:
myDict["links"] = myArray
Even if there is a struct
struct Link {
var key1, key2, name, link : String
}
and the array dictionary is
let linkDictionary = [
0: Link(key1:"a", key2: "b", name: "c", link: "d"),
1: Link(key1:"e", key2: "f", name: "g", link: "h")]
you can assign it if the value type is Any
myDict["links"] = linkDictionary
Assuming, for a second, that links really was an array, it would be:
var dictionary: [String: Any] = [
"id": "blabla",
"links": [
["key1": "a", "key2": "b", "name": "c", "link": "d"],
["key1": "e", "key2": "f", "name": "j", "link": "h"]
]
]
// retrieve links, or initialize it if not found
var links = dictionary["links"] as? [[String: String]] ?? [[String: String]]()
// add your new link to local dictionary
links.append(["key1": "k", "key2": "l", "name": "m", "link": "n"])
// update original structure
dictionary["links"] = links
Personally, though, when I see a repeating dictionary structure like your links, this screams for a real model for these objects. For example:
struct Foo {
let id: String
var links: [Link]?
}
struct Link {
let key1: String
let key2: String
let name: String
let link: String
}
var foo = Foo(id: "blabla", links: [
Link(key1: "a", key2: "b", name: "c", link: "d"),
Link(key1: "e", key2: "f", name: "j", link: "h")
])
foo.links?.append(Link(key1: "k", key2: "l", name: "m", link: "n"))
Now, in this latter example, I assumed that links was really an array, not a dictionary, but that's not really my point here. My key observation is that code is more readable and robust if you use proper custom types rather than just arrays and dictionaries.
And if you need to send and receive these model objects to some web service, you then map this model object to and from JSON. But use custom types for your actual model.
If you want to make the above types easily converted to and from JSON, you can use one of the object mapping libraries out there, so you can do something yourself, e.g.:
protocol Jsonable {
var jsonObject: Any { get }
init?(jsonObject: Any)
}
extension Foo: Jsonable {
var jsonObject: Any {
return [
"id": id,
"links": links?.map { $0.jsonObject } ?? [Any]()
]
}
init?(jsonObject: Any) {
guard let dictionary = jsonObject as? [String: Any],
let id = dictionary["id"] as? String else { return nil }
var links: [Link]?
if let linksDictionary = dictionary["links"] as? [Any] {
links = linksDictionary.map { Link(jsonObject: $0)! }
}
self.init(id: id, links: links)
}
}
extension Link: Jsonable {
var jsonObject: Any { return [ "key1": key1, "key2": key2, "name": name, "link": link ] }
init?(jsonObject: Any) {
guard let dictionary = jsonObject as? [String: Any],
let key1 = dictionary["key1"] as? String,
let key2 = dictionary["key2"] as? String,
let name = dictionary["name"] as? String,
let link = dictionary["link"] as? String else {
return nil
}
self.init(key1: key1, key2: key2, name: name, link: link)
}
}
Then you can do stuff like:
let object = try JSONSerialization.jsonObject(with: data)
var foo = Foo(jsonObject: object)!
Or:
foo.links?.append(Link(key1: "j", key2: "k", name: "l", link: "m"))
let data = try! JSONSerialization.data(withJSONObject: foo.jsonObject)
This was the solution:
var arrLinks : Array<Dictionary<String, Any>> = []
for link in myArray {
var dict : Dictionary<String, Any> = [:]
dict["key1"] = link.name
dict["key2"] = link.ghostBefore
dict["key3"] = link.ghostAfter
arrLinks.append(dict)
}
myDict["links"] = arrLinks as AnyObject
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++)
{
...
}
}
I have a few issues with chartjs which simple update method won't solve.
I wonder if there is an option to:
painlessly sort the datasets;
insert some data in between two points;
reload the whole chart without replacing the canvas with a
completely new chart?
There is no option built in, but it is pretty easy to write your own using the addData, removeData methods that Chart.js provides.
var MyBarChartMethods = {
// sort a dataset
sort: function (chart, datasetIndex) {
var data = []
chart.datasets.forEach(function (dataset, i) {
dataset.bars.forEach(function (bar, j) {
if (i === 0) {
data.push({
label: chart.scale.xLabels[j],
values: [bar.value]
})
} else
data[j].values.push(bar.value)
});
})
data.sort(function (a, b) {
if (a.values[datasetIndex] > b.values[datasetIndex])
return -1;
else if (a.values[datasetIndex] < b.values[datasetIndex])
return 1;
else
return 0;
})
chart.datasets.forEach(function (dataset, i) {
dataset.bars.forEach(function (bar, j) {
if (i === 0)
chart.scale.xLabels[j] = data[j].label;
bar.label = data[j].label;
bar.value = data[j].values[i];
})
});
chart.update();
},
// reload data
reload: function (chart, datasetIndex, labels, values) {
var diff = chart.datasets[datasetIndex].bars.length - values.length;
if (diff < 0) {
for (var i = 0; i < -diff; i++)
chart.addData([0], "");
} else if (diff > 0) {
for (var i = 0; i < diff; i++)
chart.removeData();
}
chart.datasets[datasetIndex].bars.forEach(function (bar, i) {
chart.scale.xLabels[i] = labels[i];
bar.value = values[i];
})
chart.update();
}
}
which you call like so (where myBarChart is your chart)
// sort
MyBarChartMethods.sort(myBarChart, 0)
// reload - same number of values
MyBarChartMethods.reload(myBarChart, 0, ["J", "F", "M", "A", "M", "J", "J"], [1, 2, 3, 4, 5, 6, 7])
// reload - more values
MyBarChartMethods.reload(myBarChart, 0, ["J", "F", "M", "A", "M", "J", "J", "A"], [1, 2, 3, 4, 5, 6, 7, 8])
// reload - less values
MyBarChartMethods.reload(myBarChart, 0, ["J", "F", "M", "A", "M"], [1, 2, 3, 4, 5])
Inserting 2 points is special case of reload, so you can use the same function (or write your own based on that easily)
Fiddle - http://jsfiddle.net/Lkdxxkfa/
I came to stackoverflow having the same question so what I have done is created a plugin that allows you to add a sort function to ChartJS
https://github.com/scotthsieh0503/chartjs-plugin-sort
it also allows you to pass in a 'pre-sorted' array as a reference for sorting