Sorting a list into smaller lists according to a characteristic in dart - list

Sorry for my poor explanation, I just started learning dart.
With a mock service and a json file I created a set amount of items
Example:
{
"items": [
{
"id": "01",
"type": "a"
},
{
"id": "02",
"type": "b"
},
{
"id": "03",
"type": "c"
}
]
}
when creating the list on the service it creates a single list like this:
if (json['items'] != null) {
final itemList = <ItemList>[];
json['items'].forEach((v) {
itemlistList.add(ItemList.fromJson(v));
});
return ItemList;
} else {
return [];
}
is there a way to, form the create list step to already separate them into 3 different lists for the type a, b, and c items? and if now, where and how would I divide this itemlist into 3 based on the type characteristic of each item?

Using groupBy, as suggested in this extremely similar question: Flutter/Dart how to groupBy list of maps?
import "package:collection/collection.dart";
main(List<String> args) {
var data = [
{"id": "01", "type": "a"},
{"id": "02", "type": "b"},
{"id": "03", "type": "c"},
{"id": "04", "type": "a"},
{"id": "05", "type": "a"},
{"id": "06", "type": "b"},
];
var newMap = groupBy(data, (Map obj) => obj["type"]);
print(newMap);
}

Related

How do I query an AWS OpenSearch index using a Vega visualization?

I have data in an index in JSON format, and I want to use a Vega visualization to display this (full Vega, not Vega-Lite). I've found however that every example out there is for Vega-Lite and all they're trying to do it stick their data into a time series graph. I'd like to do something different, and thus I find myself at a dead-end.
A sample doc in my index:
{
"_index": "myindex",
"_type": "doc",
"_id": "abc123",
"_version": 1,
"_score": null,
"timestamp": "2022-05-23T07:43:21.123Z",
"_source": {
"fruit": [{
"amount": 15,
"type": {
"grower_id": 47,
"grower_country": "US",
"name": "apple"
}
},
{
"amount": 43,
"type": {
"grower_id": 47,
"grower_country": "CAN",
"name": "apple"
}
},
{
"amount": 7,
"type": {
"grower_id": 23,
"grower_country": "US",
"name": "orange"
}
},
{
"amount": 14,
"type": {
"grower_id": 23,
"grower_country": "CAN",
"name": "orange"
}
}
]
}
}
What I want to do is create 2 text marks on the visualization that will display the sum of the values as follows.
Symbol1 = sum of all apples (i.e. all apples grown in the US and CAN combined)
Symbol2 = sum of all oranges (i.e. all oranges grown in the US and CAN combined)
I tried the following data element with no success:
"data": [{
"name": "mydata",
"url": {
"index": "myindex",
"body": {
"query": "fruit.type.name:'apple'",
},
}
}
]
However obviously this query isn't even correct. What I want to be able to do is return a table of values and then be able to use those values in my marks as values to drive the mark behaviour or color. I'm comfortable with doing the latter in Vega, but getting the data queried is where I'm stuck.
I've read and watched so many tutorials which cover Vega-Lite, but I'm yet to find a single working example for Vega on AWS OpenSearch.
Can anyone please help?

What's the best way to sort MAP<String, Object> by value in Dart programming?

I'm new to dart programming, I came from a Javascript environment
everything is fresh to me and I really have no Idea how this sorting works
in dart.
Here's an example from my API
List example = [
{"id": "1", "age": "20"},
{"id": "2", "age": "21"},
{"id": "3", "age": "22"},
]
Before I will assign "example" to other variables eg.
var example2 = example;
I want to sort it by "age", I found libs and other "LONG" solutions out there but feels like there's another way.. Thanks in advance!
There is sort function for list. Try reading the documentation a bit:
void main() {
List example = [
{"id": "1", "age": "20"},
{"id": "2", "age": "19"},
{"id": "3", "age": "22"},
{"id": "4", "age": "9"},
];
print(example);
example.sort((x,y) => x["age"].compareTo(y["age"]));
print(example);
}
EDIT: Your definition should contain integers logically:
void main() {
List example = [
{"id": 1, "age": 20},
{"id": 2, "age": 19},
{"id": 3, "age": 22},
{"id": 4, "age": 9},
];
print(example);
example.sort((x,y) => x["age"].compareTo(y["age"]));
print(example);
}

Elastic Search Sort

I have a table for some activities like
[
{
"id": 123,
"name": "Ram",
"status": 1,
"activity": "Poster Design"
},
{
"id": 123,
"name": "Ram",
"status": 1,
"activity": "Poster Design"
},
{
"id": 124,
"name": "Leo",
"categories": [
"A",
"B",
"C"
],
"status": 1,
"activity": "Brochure"
},
{
"id": 134,
"name": "Levin",
"categories": [
"A",
"B",
"C"
],
"status": 1,
"activity": "3D Printing"
}
]
I want to get this data from elastic search 5.5 by sorting on field activity, but I need all the data corresponding to name = "Ram" first and then remaining in a single query.
You can use function score query to boost the result based on match for the filter(this case ram in name).
Following query should work for you
POST sort_index/_search
{
"query": {
"function_score": {
"query": {
"match_all": {}
},
"boost": "5",
"functions": [{
"filter": {
"match": {
"name": "ram"
}
},
"random_score": {},
"weight": 1000
}],
"score_mode": "max"
}
},
"sort": [{
"activity.keyword": {
"order": "desc"
}
}]
}
I would suggest using a bool query combined with the should clause.
U will also need to use the sort clause on your field.

Whats the best way to add a field to the last occurrence object in an array with Ramda?

Let's say I have a simple array of objects, that all have a type field :
let arr = [
{
"name": "First",
"type": "test"
},
{
"name": "Second",
"type": "test"
},
{
"name": "Third",
"type": "test2"
},
{
"name": "Fourth",
"type": "test2"
},
{
"name": "Fifth",
"type": "test3"
},
{
"name": "Sixth",
"type": "test3"
}
]
Using Ramda what is the best way to add a field to only the last occurrence of each types?
to get :
let newArr = [
{
"name": "First",
"type": "test"
},
{
"name": "Second",
"type": "test",
"last": true
},
{
"name": "Third",
"type": "test2"
},
{
"name": "Fourth",
"type": "test2",
"last": true
},
{
"name": "Fifth",
"type": "test3"
},
{
"name": "Sixth",
"type": "test3",
"last": true
}
]
I can't really wrap my head around it! Thanks in advance! :)
Here's one possible solution:
// f :: [{ type :: a }] -> [{ type :: a, last :: Boolean }]
const f = R.addIndex(R.map)((x, idx, xs) =>
R.assoc('last',
R.none(R.propEq('type', x.type), R.drop(idx + 1, xs)),
x));
For each value in the list we look ahead to see whether there is a subsequent value with the same type property.
I'm making the guess that your data is grouped as displayed and that elements of different types are not interspersed. If that guess is wrong, there would need to be a different solution.
My version involves two helper functions, one which groups a list according to a predicate which reports whether two (consecutive) values belong together:
const breakWhen = R.curry(
(pred, list) => R.addIndex(R.reduce)((acc, el, idx, els) => {
if (idx === 0 || !pred(els[idx - 1], el)) {
acc.push([el])
} else {
acc[acc.length - 1].push(el);
}
return acc;
}, [], list)
);
And the second a Lens which focuses on the last element of a list:
const lastLens = R.lens(R.last, (a, s) => R.update(s.length - 1, a, s));
With these two, you can build a function such as this:
const checkLasts = R.pipe(
breakWhen(R.eqProps('type')),
R.map(R.over(lastLens, R.assoc('last', true))),
R.flatten
);
checkLasts(arr);
The implementation of breakWhen is pretty awful. I'm sure there's something better. The function combines ideas from Ramda's splitEvery and splitWhen
This is slightly different from David Chambers' solution as it doesn't add a last: false property to the remaining elements. But obviously it's more complex. And either of them would fail if the data is not grouped as expected.

Failed to implement computed property in emberjs

My fixture data contains multiple array.Out of this multiple array cart_items contains some product data.
I am trying to calculate total no of products available in cart data (based on length of cart_items items) but i am not able to calculate no of items are present in cart_items.
In router i have selected application fixture as model for current route,as follow :
Astcart.IndexRoute = Ember.Route.extend({
model: function() {
return Astcart.Application.find();
}
});
Computed property code :
Astcart.IndexController = Ember.ArrayController.extend({
tot_cart_prd: function() {
return this.get("model.cart_items").get('length');
}.property("#each.isLoaded")
});
And my fixture data is :
Astcart.Application.adapter = Ember.FixtureAdapter.create();
Astcart.Application.FIXTURES = [
{
"logo_url": "img/logo.jpg",
"logged_in": {
"logged": true,
"username": "sachin",
"account_id": "4214"
},
"category_list": [
{
"id": "1",
"name": "Mobiles & Accessories"
},
{
"id": "2",
"name": "Computers & Software"
},
{
"id": "3",
"name": "Fashion"
},
{
"id": "4",
"name": "Electronics"
},
{
"id": "5",
"name": "Watches & Jewelry"
},
{
"id": "6",
"name": "Health & Beauty"
},
{
"id": "7",
"name": "Games"
},
{
"id": "8",
"name": "Books & Entertainment"
},
{
"id": "9",
"name": "Gaming"
},
{
"id": "10",
"name": "Shoes & Bags"
}
],
"cart_items": [
{
"id": "1",
"name": "Samsung Galaxy Tab 2",
"qty": "1",
"price": "1245.12",
"subtotal": "7842.23"
},
{
"id": "2",
"name": "Samsung Galaxy Tab 2",
"qty": "1",
"price": "1245.12",
"subtotal": "7842.23"
},
{
"id": "3",
"name": "Samsung Galaxy Tab 2",
"qty": "1",
"price": "1245.12",
"subtotal": "7842.23"
}
]
}
];
I have posted my code here(JSFiddle).
Can any one tell me why this.get("model.cart_items") is returning null?
Because your IndexController receive an array of Astcart.Application, from the route. You need to iterate in each application and get the length of each category list .
Your computed property need to be the following:
Astcart.IndexController = Ember.ArrayController.extend({
tot_cart_prd: function() {
var result = this.get('model').map(function(application) {
return application.get('category_list.length');
});
return result;
}.property('model.#each.category_list.length')
});
Here's an updated fiddle http://jsfiddle.net/marciojunior/PZZym/
I just looked at this and your core issue has something to do with the relationship setup between Application and Cart_items. The reason that this.get("model.cart_items").get('length') is failing is that this.get("model.cart_items") returns null. If you can get your relationship working you should be on the right track. I don't know anything about EmberModel, so I can't be of much help there.