Related
can i sort about value in map within list??
expect result: [1,2,3,4,6,7]
List a = [
[
{'g': 1},
{'g': 5},
{'g': 3}
],
[
{'g': 7},
{'g': 2}
],
[
{'g': 4}
]
];
Loop through the map of the data a and add the value to a list.
Sort the list
List a = [
[
{'g': 1},
{'g': 5},
{'g': 3}
],
[
{'g': 7},
{'g': 2}
],
[
{'g': 4}
]
];
List<int> values = [];
for (var o in a) {
for (var i in o) {
values.add(i['g']);
}
}
values.sort((a, b) => a - b);
print(values);
Output:
[1, 2, 3, 4, 5, 7]
I have a working, simple highchart chart which plots 'score' against 'time'. There's a demo here: http://jsfiddle.net/akfwsq1e/.
The series data is in the form [time, score]:
"data": [
[1540398983, 3],
[1540398983, 2],
[1540398983, 3],
[1540398983, 2],
[1540398983, 4],
[1540485383, 3]
]
However, I need to append more meta-data as I'd like to extend the chart with filters etc in future. This means that the data from the API is returning named objects:
"data": [
{ 'dateCompleted': 1540398983, 'score': 3, 'category': 'A' },
{ 'dateCompleted': 1540398983, 'score': 2, 'category': 'C' },
{ 'dateCompleted': 1540398983, 'score': 3, 'category': 'A' },
{ 'dateCompleted': 1540398983, 'score': 2, 'category': 'B' },
{ 'dateCompleted': 1540398983, 'score': 4, 'category': 'A' },
{ 'dateCompleted': 1540485383, 'score': 3, 'category': 'C' }
]
For now I'm not too concerned with the filtering, I just need to get the chart to plot the same as it does when using simple object values. When I use named values though the chart silently fails to plot anything.
I can't seem to figure out from the documentation how Highcharts 'knows' which values from a named-object to plot.
Can anyone suggest how to get this working?
Many thanks.
If you won't change the structure of object recieved from server, you could implement your own data parse function, which takes the data with specific structure, and returns the data specially prepared for Highcharts.
Actually it's a bit piece of cake, so I wrote that function:
function mapData(data) {
let arr;
arr = data.map(point => {
return {
x: point.dateCompleted,
y: point.score,
category: point.category
}
})
return arr
}
Live example: http://jsfiddle.net/1jp8v6ns/
Apparently you need to call the values to plot 'x' and 'y' (https://api.highcharts.com/highcharts/series.column.data). So this works:
"data": [
{ 'x': 1540398983, 'y': 3, 'category': 'A' },
{ 'x': 1540398983, 'y': 2, 'category': 'C' },
{ 'x': 1540398983, 'y': 3, 'category': 'A' },
{ 'x': 1540398983, 'y': 2, 'category': 'B' },
{ 'x': 1540398983, 'y': 4, 'category': 'A' },
{ 'x': 1540485383, 'y': 3, 'category': 'C' }
]
I have 4 fields in a document which is name, online, like and score. I want to ordering by multiple fields and conditions collection of million documents with pagination.
Example some documents :
My user documents :
{ "_id": 1, "name": "A", "online": 1, "like": 10, "score": 1 },
{ "_id": 2, "name": "B", "online": 0, "like": 9, "score": 0 },
{ "_id": 3, "name": "C", "online": 0, "like": 8, "score": 1 },
{ "_id": 4, "name": "D", "online": 1, "like": 8, "score": 0 },
{ "_id": 5, "name": "E", "online": 1, "like": 7, "score": 1 },
{ "_id": 6, "name": "F", "online": 0, "like": 10, "score": 0 },
I will explain my point with the following example (example using an array).
Example in ruby language, I have an array structure looks like :
[["A", 1, 10, 1],
["B", 0, 9, 1],
["C", 0, 8, 1],
["D", 1, 8, 0],
["E", 1, 7, 1],
["F", 0, 10, 0]]
If online is 1 should be sort again by descending of like, but when online is 0 should be sort again by descending of score.
example sort :
list.sort{|a, b| a[1] == 1 ? ([-a[1], -a[2]] <=> [-b[1], -b[2]]) : ([-a[1], -a[3]] <=> [-b[1], -b[3]]) }
Result like this :
[["A", 1, 10, 1],
["D", 1, 8, 0],
["E", 1, 7, 1],
["B", 0, 9, 1],
["C", 0, 8, 1],
["F", 0, 10, 0]]
That is an array sort, but my problem is I have collection of mongodb and million documents, I can't use an array sort, because it will heavy load to database, should get all documents and convert to array (including sorting) and than paginate them, I think that's a bad idea.
I have try with order()/order_by() mongoid's optional method like :
User.
order_by([:online, :desc], [:like, :desc], [:score, :desc]).
hint(online: -1, like: -1, score: -1).
page(1).per(10)
But that query is only order by online and score, is there sort method in mongoid like an array sorting? or there is something like bubble sort in mongodb?
same problem here : Ruby on Rails: Concatenate results of Mongoid criterias and paging, merge method doesn't helped me because it can be replace the first criteria.
Using aggregation $cond
User.collection.aggregate([
{
"$project" => {
"id" => 1,
"name" => 1,
"online" => 1,
"like" => 1,
"score" => 1,
"sort" => {
"$cond" => {
"if" => {
"$eq" => ["$online", 1]
},
"then" => "$like",
"else" => "$score"
}
}
}
},
{
"$sort" => {
"online" => -1,
"sort" => -1,
"id" => 1
}
},
{
"$skip" => 0
{
"$limit" => 12
}
])
references :
https://docs.mongodb.com/manual/reference/operator/aggregation/cond/
https://www.oodlestechnologies.com/blogs/How-to-use-Conditional-Statements-for-sorting-data-in-MongoDB
Assuming fields score , like and online are numeric , based on the condition we can create an auxiliary field that is a sum of online and like or online and score. Following which we can sort on the new field and any other required field.
db.collection aggregate([ {"$addFields": {"refCount":{"$cond":{"if":{"$eq":["$online", 1]}, "then":{"$add": ["$online", "$like"]}, "else": {"$add": ["$online", "$score"]} } } }},{ "$sort": { "refCount": -1 ,"id":1} },{"$project":{"id": 1, "name": 1, "online": 1, "like": 1,"score":1}},{ "$limit": 10 } ])
The first stage of the pipeline build the auxiliary field refcount. This field is then used in $sort along with id . In the next stage we have a projection of required fields , followed by limit clause.
Instead of numeric , if these fields were strings, a padded concatenation of fields would be required.
I have this json data (actual data is a lot longer, that's why I need only 2)
[
{
"id": 1,
"user_id": 1,
"event_id": 1,
"creator_id": 1,
"event_name": "Poker",
"cruise_ship_name": "Royal Cruise",
},
{
"id": 2,
"user_id": 1,
"event_id": 2,
"creator_id": 1,
"event_name": "Ballroom",
"cruise_ship_name": "Celebrity Infinity",
},
{
"id": 3,
"user_id": 1,
"event_id": 3,
"creator_id": 1,
"event_name": "Tennis",
"cruise_ship_name": "Mediterranean",
}
]
I want to combine all data and get only specific fields (event_name and cruise_ship_name)
So in my final json format
it will be:
[
{
"event_name": "Mexican Fiesta",
"cruise_ship_name": "Celebrity Infinity",
}
]
I have been looking at this example:
#object.to_json {:include => [ :assocation_a, :assocation_b ]}
but not sure what :association_a and :association_b are.
Suppose you have an array of hashes:
events = [
{
"id": 1,
"user_id": 1,
"event_id": 1,
"creator_id": 1,
"event_name": "Poker",
"cruise_ship_name": "Royal Cruise",
},
...
]
You can iterate through each value in your hash, only keeping values of interest:
events.each do |event_hash|
event_hash.keep_if { |key, _| [:event_name, :cruise_ship_name].include?(key) }
end
puts events
The to_json method accept parameters which allow you include specific attributes:
#object.to_json(only: [:event_name, :cruise_ship_name])
The include: :assocation_a option to object, allowing the object association in the assocation_a model to be converted to JSON as well.
array = [
[ 1, "name1" ],
[ 2, "name2" ],
[ 3, "name3" ],
[ 4, "name4" ]
]
I want to make this as an array of hashes like this:
array_hash = [{ "id" => 1, "name" => "name1" },
{ "id" => 2, "name" => "name2" },
{ "id" => 3, "name" => "name3" },
{ "id" => 4, "name" => "name4" }]
array = [
[ 1, "name1" ],
[ 2, "name2" ],
[ 3, "name3" ],
[ 4, "name4" ]
]
array.map { |e| ['id', 'name'].zip(e).to_h }
#⇒ [
# {"id"=>1, "name"=>"name1"},
# {"id"=>2, "name"=>"name2"},
# {"id"=>3, "name"=>"name3"},
# {"id"=>4, "name"=>"name4"}
# ]
The only interesting here is Enumerable#zip, that “merges” arrays.
I'd use:
array.map { |id, name| { 'id' => id, 'name' => name } }
#=> [{"id"=>1, "name"=>"name1"},
# {"id"=>2, "name"=>"name2"},
# {"id"=>3, "name"=>"name3"},
# {"id"=>4, "name"=>"name4"}]
The .to_h method is new to Ruby 2.x. Here is an alternative for anyone on 1.9.x or lower.
array = [[ 1, "name1" ], [ 2, "name2" ], [ 3, "name3" ], [ 4, "name4" ]]
array.inject([]) { |a, r| a << { id: r[0], name: r[1] } }