How do I render a Map data structure in an Ember template? - ember.js

I use Ember 2.8. There exists Map data structure in Ember. It should be iterable. However there's no examples how to enumerate through it and render it.
Assuming that both keys and values in my map are JS objects that have some 'name' set, I tried in Emblem:
each myMap.keys as |key|
p = key.name
each myMap.values as |value|
p = value.name
/ each myMap as |key, value| //this one causes build error
/ p = key.name
/ p = value.name
None of these syntaxes seem to work and render something more than 'undefined' empty space.
Do any of you know how to render a Map in Ember?

Turns out it was enough to use native JS Map.
My Map ended up using pairs Object: Array[Object].
In Emblem template:
each myMap as |value key| // <--- notice the order!
p {{key.name}}
p {{key.date}}
each value as |item| // values from map are arrays so I enumerate through them as well
p {{item.name}}
p {{item.details}}
In controller:
myMap: function() {
var myMap = new Map();
myMap.set(
{name: 'keyname', date: 'keydate'},
[{name: 'itemname', details: 'itemdetails'}, {name: 'itemname2', etails: 'itemdetails2'}]
);
// ... etc set more pairs
return myMap;
}.property();

Are you looking for something like each-in helper?
Usage:
{{#each-in obj as |key value|}}
{{key}}:{{value}}<br>
{{/each-in}}
Have a look at this sample demo.

Related

What's the best way to find an object from a string in kotlin?

I have an app that is reading an ingredients list. At this point I've already retrieved a list of the 2500 most common ingredients. So I've got a list of, say 10 ingredients as strings, and a list of 2500 ingredients, with names as well as other properties. If an ingredient in this list of strings matches the name of an ingredient in the list of ingredients, I'd like to add it to another list third list, of ingredients that exist. The only way I know how to do that is with basically a for loop.
I'd do it as
fun compareLists(listOfIng: List<String>): List<ListIngredientsQuery.Item> {
var returnList = mutableListOf<ListIngredientsQuery.Item>()
for (ing in listOfIng) {
for (serverIngredient in MyApp.metaIngredientList!!) {
if (serverIngredient.name() == ing) {
returnList!!.add(serverIngredient)
}
}
}
return returnList
}
Which would technically work, but I have to imagine there's a better, faster way than iterating over 2500 items, as many times as there are Ingredients in an Ingredient list. What is the like, proper, preferred by real developers, way of doing this.
As each ingredient name is unique, you can use hash map for storing your 2500 ingredients with its name as the key. This way you do not need to loop over that huge collection any more, but just look thing up by the name and let the hash map deal with it.
To put some code to what Marcin said, here is what I would do:
fun compareLists(listOfIng: List<String>) =
MyApp.metaIngredientList!!
.associateBy { it.name() }
.let { metaIngredientMap -> listOfIng.mapNotNull { metaIngredientMap[it] }}
Or if we wanna avoid using !!
fun compareLists(listOfIng: List<String) =
MyApp.metaIngredientList
?.associateBy { it.name() }
?.let { metaIngredientMap -> listOfIng.mapNotNull { metaIngredientMap[it] }}
?: emptyList<ListIngredientQuery.Item>()
Of course, ideally, you would want that MyApp.metaIngredientList to be already a Map and not convert it into a Map for each operation

How to filter query result to list of strings

I have a query result same as below:
var ptns = from p in db.Patients
select p;
This query returns a list of patients, but I need to filter the result based on DoctorNameID. The DoctorNameID should be in list of doctors as below:
List<string> listofDoctors = usrtodrs.Split(',').ToList();
I have searched a lot but I don't know how to do this. I have tested this query which doesn't work:
var ptns1 = from d in listofDoctors
join p in ptns.ToList() on d equals p.DoctorNameID
select p;
And also this query:
var ptns1 = ptns.ToList()
.Where(a => listofDoctors.Equals(a.DoctorNameID))
.ToList();
Any help?
You can use Contains extension and get the desired result.
var ptns1 = ptns.Where(x => listofDoctors.Contains(x.DoctorNameID)).ToList();
Refer the C# Fiddle with sample data.

Flattening data with same performance for recursive $query->with

I am using Laravel 5.5.13.
Thanks to awesome help from awesome member of SO I currently get nested (and repeated) data by doing this:
public function show(Entity $entity)
{
return $entity->with([
'comments' => function($query) {
$query->with([
'displayname',
'helpfuls' => function($query) {
$query->with('displayname');
}
]);
},
'thumbs' => function($query) {
$query->with('displayname');
}
])->firstOrFail();
}
This gives me example data like this: https://gist.githubusercontent.com/blagoh/ee5e70dfe35aa5c68b2d445c63887aaa/raw/a0612fb770a27eaacfbb1e87987aa4fd8902a8a3/nested.json
However I want to flatten it to this: https://gist.github.com/blagoh/7076be06c400d04941a0593267e11e81 - look at the version diff we see the changes:
https://gist.github.com/blagoh/7076be06c400d04941a0593267e11e81/revisions#diff-cb567797700e4d4b63b106653162c671R15
We see line 15 is now "helpful_ids": [] and has just array of ids, and then all displaynames and helpfuls were moved to top of array on line 45 and 78.
Is it possible to flatten this data, while keeping same query performance (or better)?

Why is 'array' being passed to the filter function?

JSBin Example
In the following code, 'array' is simply an array of integers, 'items' is a list of objects, and 'coprop' is a computed filter of 'items' using 'array' (which may change) to decide which elements of 'items' belong in 'coprop'.
The desired result is just those elements of 'items' that have a 'value' in 'array'.
The actual result is a javascript error when the elements of 'array' are (for some reason) passed to the filtering function in addition to the elements of 'items'. That triggers a 'typeerror: i.get is not function' message.
array: [ 4, 5, 6 ],
items: function() {
return this.get('store').peekAll('item');
}.property(),
coprop: Ember.computed.filter('items', function(i,idx,ary) {
console.log('i = ' + i);
return this.get('array').isAny(i.get('value'));
}).property('items','array')
Please Note This is a simplified example to demonstrate the problem. The filtering function is more complex than shown here, but this does show the issue quite clearly.
Actual Output
"i = <App.Thing:ember409:1>"
"i = <App.Thing:ember410:2>"
"i = <App.Thing:ember411:3>"
"i = <App.Thing:ember412:4>"
"i = 4"
"error"
"TypeError: i.get is not a function
The Questions
Why is 'array' being passed to the filter function as elements to filter?
How do I ensure that 'coprop' will be updated if 'array' changes?
It's because of the property suffix on it. Maybe you could filter it like this:
coprop: Ember.computed('array.[]', 'items.[]', function(){
let arr = this.get('array');
return this.get('items').filter(i => arr.contains(i.get('value')));
})

What is the difference between a list of tuples and a list of objects?

Please see I want list employee objects. So I have below two options.
List<Tuple<int, string, string, string>>
List<Employee>where Employee is class contains 4 properties.
My doubt is what should I use(tuple or list of employee object?
If it is List<Employee> then in which scenario I should use List<Tuple<int, string, ...>>.
You should not use tuples unless you are doing some sort of arithmetic operation where tuple would be an acceptable and widely understood method of supplying values. Tuples make it a maintenance nightmare for anyone who is not familiar with your process as you built it.
Edit: Think about the difference between seeing:
var employeeList = DAL.getEmployees();
var activeEmployees = employeeList.Where(employee => employee.IsActive);
vs
var employeeTuple = DAL.getEmployees();
var activeEmployees = employeeTuple.Where(employee => employee.Item3);
In the second example, I know THAT you created an active employee list, but I don't know HOW you did it.
That's rather obvious. If you already have the Employee class then using List<Employee> is straightforward:
List<Employee> list = new List<Employee>();
list.Add( e );
...
Employee e = list.Where( i => i.Name == "John" ).FirstOrDefault();
whereas using List<Tuple<...>> is at least cumbersome:
List<Tuple<....>> list = new List<Tuple<....>>();
list.Add( new Tuple<...>( e.Name, e.Surname, e.Whateverelse, e.YetAnother ) );
...
// retrieve the tuple
var tuple = list.Where( i => i.Item1 == "John" );
// make Employee out of it
Employee e = new Employee( e.Item1, e.Item2, e.Item3, e.Item4 );