I wanted to modify the response for array of object - node.js

I wanted to modify the response for array of object.
I have below result.
And i wanted to change the response to specific response.
let result = [
{
team_id: 1,
team_name: 'Avengers',
participant1: 98,
participant2: 99,
participant3: 100,
participant4: 101,
phase1: 0,
phase2: 0,
phase3: 0,
phase4: 0,
phase5: 0,
participant1_name: 'test 1003',
participant2_name: 'test 1002',
participant3_name: 'test 1004',
participant4_name: 'test 1005'
}
]
And wanted to convert to below.
[
{
"team_id": 1,
"team_name": "Avengers",
"phase1": 0,
"phase2": 0,
"phase3": 0,
"phase4": 0,
"phase5": 0,
"participantDetails": [
{
"participant1": 98,
"participant1_name": "test 1003"
},
{
"participant2": 99,
"participant2_name": "test 1002"
},
{
"participant3": 100,
"participant3_name": "test 1004"
},
{
"participant4": 101,
"participant4_name": "test 1005"
}
]
}
]
I have tried below: -
const data = result.map((elem) => {
const participantDetails = [];
for (let keys in elem) {
if (keys.startsWith('participant')) {
console.log('elem:-',elem);
participantDetails.push({
[keys]: elem[keys]
})
delete elem[keys]
}
}
return {
...elem,
participantDetails: participantDetails
}
});
I have filter participant but not sure how to filter names also.
And they are having different positions for that.
Please help thanks in advance.

You're already in the right direction. You don't have to filter for participant names since you can easily derive them once you filtered the participant.
Here's my approach:
let result = [
{
team_id: 1,
team_name: 'Avengers',
participant1: 98,
participant2: 99,
participant3: 100,
participant4: 101,
phase1: 0,
phase2: 0,
phase3: 0,
phase4: 0,
phase5: 0,
participant1_name: 'test 1003',
participant2_name: 'test 1002',
participant3_name: 'test 1004',
participant4_name: 'test 1005',
},
];
for (let obj of result) {
let participantDetails = [];
Object.keys(obj)
.filter((key) => /^participant\d+$/.test(key))
.forEach((key) => {
participantDetails.push({
[key]: obj[key],
[`${key}_name`]: obj[`${key}_name`],
});
delete obj[key];
delete obj[`${key}_name`];
});
obj.participantDetails = participantDetails;
}
console.log(JSON.stringify(result, null, 4));
Notice that I used regex to filter strictly on participant. From there, I can derive the values for participant_names and push them into the participantDetails array.
It is also important to note that you are modifying the values of the result array. If you want to keep those values, you can use map instead to create a new instance of the array.

Related

Mongoose/Node: selecting element WITHOUT field/column name

So I have document like this
datatable: [{
data:[
["ABC", 123, 10, 1],
["ABC", 121, 10, 1],
["DDE", 13, 10, 1],
["OPP", 523, 10, 1]
]
}]
I want to select with a parameter "ABC" and would return arrays only with "ABC" like this:
datatable: [{
data:[
["ABC", 123, 10, 1],
["ABC", 121, 10, 1]
]
}]
Im starting with this code:
router.get("/", (req, res) => {
model.find({}).then(val=> {
res.send(val)
})
})
I cant find ways to find the value without the fieldname.
I tried using $elemMatch. Other ways needs a matching column name with the value.

Echarts Pie - pieces without color

My problem appears to be close to THIS post (without solution).
Could anybody help me with a Echarts Pie withour colors? I have 2 versions of Echarts, an official and another modified, and the problem occours only with the official version (latest).
I am using data from PHP variables. Official version works when I change data to static numbers, but loose colors with static data. IMPORTANT: I have the correct data in the variables, because the pie appears with correct data, but black & white only.
Thanx any help.
Here is my pie code:
<div id="main2" style="width: 600px;height:400px;"></div></td></tr></table>
<script>
var csimpa = '<?php echo $csimpa[$mescert] ?>';
var cesprega = '<?php echo $cesprega[$mescert] ?>';
var cespdefa = '<?php echo $cespdefa[$mescert] ?>';
var cinta = '<?php echo $cinta[$mescert] ?>';
var cespparta = '<?php echo $cespparta[$mescert] ?>';
// Create a pie chart:
echarts.init(document.getElementById('main2')).setOption({
/*title : {
text: 'CERTID\u00d5ES EXPEDIDAS',
subtext: '2018',
x:'center'
},*/
tooltip : {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
/*legend: {
orient: 'vertical',
left: 'left',
data: ['CS','CI']
},*/
visualMap: {
show: false,
min: 80,
max: 600,
inRange: {
colorLightness: [0, 1]
}
},
series : [
{
name: 'CERTID\u00d5ES',
type: 'pie',
radius : '55%',
center: ['50%', '60%'],
data:[
{value: csimpa, name:'Simplificada'},
//{value:<? echo $cespoaba[$mescert] ?>, name:'Esp - OAB'},
{value: cesprega, name:'Esp - Existencia'},
{value: cespdefa, name:'Esp - Definir'},
{value: cinta, name:'Inteiro Teor'},
{value: cespparta, name:'Esp - Participa'}
]/*.sort(function (a, b) { return a.value - b.value; }),
roseType: 'radius'*/,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
animationType: 'scale',
animationEasing: 'elasticOut',
animationDelay: function (idx) {
return Math.random() * 200;
}
}
]
});
</script>
Make sure if the data is coming through dynamically, that it is loaded before the chart finishes loading. You need the data fully loaded so that the chart can use it.
Instead of giving name and value inside the data create an array of objects and define it in a variable and pass it inside series data.
The values used are just for demo
you can use an array of object creation like objectDemo or objectDemo2
let values = [224, 214, 139, 312, 176]
let categories = ['Simplificada', 'Esp - Existencia', 'Esp - Definir', 'Inteiro Teor', 'Esp - Participa']
let objectDemo2 = values.map((d,i) => {
return {
name: categories[i],
value: values[i]
}
})
let objectDemo = [
{value: 224, name:'Simplificada'},
{value: 214, name:'Esp - Existencia'},
{value: 139, name:'Esp - Definir'},
{value: 312, name:'Inteiro Teor'},
{value: 176, name:'Esp - Participa'}
]
option = {
tooltip : {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
visualMap: {
show: true,
min: 80,
max: 600,
inRange: {
colorLightness: [0, 1]
}
},
series : [
{
name: 'CERTID\u00d5ES',
type: 'pie',
radius : '55%',
center: ['50%', '60%'],
data: objectDemo2/*.sort(function (a, b) { return a.value - b.value; }),
roseType: 'radius'*/,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
animationType: 'scale',
animationEasing: 'elasticOut',
animationDelay: function (idx) {
return Math.random() * 200;
}
}
]
};
You can see the working of the above code

Chart JS change pointBackgroundColor based on data value

So I have created a basic line chart using Chartjs. How would I go about changing the color of the points (pointBackgroundColor) depending on the value of the data? For example, if the data point is less than 10 it changes to red, or if the data point is between 10 and 20 it changes to blue?
const CHART = document.getElementById("lineChart");
let lineChart = new Chart(CHART, {
type: 'line',
data: {
labels: ["5/10/2010", "5/11/2010", "5/12/2010", "5/13/2010", "5/14/2010", "5/15/2010", "5/16/2010"],
datasets: [
{
label: "Theta",
fill: false,
lineTension: 0,
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(9,31,62)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(0,191,255)",
pointBackgroundColor: "rgba(0,191,255)",
pointBorderWidth: 5,
pointBorderRadius: 5,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: [15, 28, 11, 3, 34, 65, 20],
}
]
},
options: {
maintainAspectRatio: false,
responsive: true,
legend: {
display: false,
},
scales: {
yAxes:[{
ticks: {
fontColor: "#091F3e",
beginAtZero: true,
steps: 10,
stepSize: 10,
max: 100
},
gridLines: {
display: false
}
}],
xAxes:[{
ticks: {
fontColor: "#091F3e",
fontSize: "10",
},
gridLines: {
display: false
}
}]
}
}
});
You can use a closure on any option and manipulate the returned value according to the context. In the example bellow I'm the pointBackgroundColor is red when the current value is greater then 0 and blue otherwise.
pointBackgroundColor: function (context) {
let value = context.dataset.data[context.dataIndex];
return value > 0
? 'red'
: 'blue';
},
Here is another thing that may help you Change bar color depending on value.
Its original answer from Tot Zam
Adding the code sample in case the link doesn't work.
var colorChangeValue = 50; //set this to whatever is the decidingcolor change value
var dataset = myChart.data.datasets[0];
for (var i = 0; i < dataset.data.length; i++) {
if (dataset.data[i] > colorChangeValue) {
dataset.backgroundColor[i] = chartColors.red;
}
}
myChart.update();
Its about bars background, but you can try work around and find same solution.

How do I read a script array into duktape?

I'm new to duktape and trying to read a config
from a script file:
var config =
[
{ ready: true, name: "dev1", on: 8, off: 9 },
{ ready: true, name: "dev2", on: 10, off: 11 },
{ ready: true, name: "dev3", on: 18, off: 21 },
{ ready: true, name: "dev4", on: 13, off: 17 }
];
duktape has great documentation, but I can not seem to find
any example of what I am trying to accomplish.
I have managed to read a single dimension array. (Not sure if it is the best or proper way to to do it)
// var one_dim = [ "hello", "world", "single", "dimension", "array" ] ;
void init_one_dimension(void) {
duk_get_prop_string(ctx, -1, "one_dim");
if(duk_is_array(ctx, -1)) {
printf("Found array\n");
duk_enum(ctx, -1, DUK_ENUM_ARRAY_INDICES_ONLY);
while (duk_next(ctx, -1 , 0 )) {
duk_get_prop_index(ctx, -1, 0);
duk_get_prop_string(ctx, -4, duk_get_string(ctx, -1));
printf("%s\n", duk_get_string(ctx, -1));
show_stack(ctx, "STACK");
duk_pop(ctx); // get_prop_string
duk_pop(ctx); // get_prop_index
duk_pop(ctx); // duk_next
}
duk_pop(ctx); // duk_enum
duk_pop(ctx); // duk_get_prop_string
}
}
Multi-dimensional arrays escape me. Any help would be appreciated.
The 'config' object you have at the top, is not a multi-dimensional array but instead an array containing dictionaries. So with the enum code you have already, you just need to access the keys (ready, name, etc) like normal object properties.
duk_get_prop_string

node_redis get zrange withscores

Does anybody know how can I get members with scores by node redis?
I tried something like this:
client.ZRANGE(key, 0, -1, withscores, function(err, replies) {
});
Thanks.
This code looks good. Check out the following link for retrieving what you want :
http://ricochen.wordpress.com/2012/02/28/example-sorted-set-functions-with-node-js-redis/
Added the code here from that link example in case it is ever removed.
var rc=require('redis').createClient();
var _=require('underscore');
rc.zincrby('myset', 1, 'usera');
rc.zincrby('myset', 5, 'userb');
rc.zincrby('myset', 3, 'userc');
rc.zrevrange('myset', 0, -1, 'withscores', function(err, members) {
// the resulting members would be something like
// ['userb', '5', 'userc', '3', 'usera', '1']
// use the following trick to convert to
// [ [ 'userb', '5' ], [ 'userc', '3' ], [ 'usera', '1' ] ]
// learned the trick from
// http://stackoverflow.com/questions/8566667/split-javascript-array-in-chunks-using-underscore-js
var lists=_.groupBy(members, function(a,b) {
return Math.floor(b/2);
});
console.log( _.toArray(lists) );
});
rc.quit();
Seems your code is right. The following is the syntax to get zrange.
without score:
redisClient.zrange(keyName,start,stop,function(err,result){
//result is array
// every index will give you member name
})
Ex :
redisClient.zrange("mySortedset",-1,-1,function(err,result){
//result is array
// every index will give you member name
})
with score:
redisClient.zrange(keyName,start,stop,'withscores',function(err,result){
//result is array
// here even index will hold member
// odd index will hold its score
})
Ex :
redisClient.zrange("mySortedset",-1,-1,'withscores',function(err,result){
//result is array
// here even index will hold member
// odd index will hold its score
})
I tried with the prior accepted answers but i could not get the result i want and later i tried with the following code and got appropriate result,
Original output:
[ 'player:522',
'19685',
'player:164',
'19594',
'player:807',
'19171',
'player:694',
'19165',
'player:905',
'19108',
'player:859',
'19087',
'player:432',
'18973',
'player:515',
'18831',
'player:163',
'18750',
'player:4',
'18552' ]
Expected output:
{
"player:522": "19685",
"player:164": "19594",
"player:807": "19171",
"player:694": "19165",
"player:905": "19108",
"player:859": "19087",
"player:432": "18973",
"player:515": "18831",
"player:163": "18750",
"player:4": "18552"
}
Solution:
redisClient.ZREVRANGE('daily', 1, 10, 'WITHSCORES', function(err, result) {
result = _.fromPairs(_.chunk(result, 2));
return res.status(200).json(result);
});
The right approach for versions ^2.0,
var args = [ key,to, from ];
redisClient.zrevrangebyscore(args,function(err,data){
Vanilla JS Solution
Redis call:
redisClient.zrange(keyName, start, stop, 'withscores', function(err, result) {
// result.reduce ... (See below)
}
Here is a Vanilla-JS solution that I came up with pretty quickly.
For me, personally, it does not make sense to import underscore or any other library to perform such an easy task:
result.reduce(function (a, c, i) {
var idx = i / 2 | 0;
if (i % 2) {
a[idx].score = c;
} else {
a[idx] = { id: c };
}
return a;
}, []);
Assuming this input:
['player1', 13, 'player2', 11, 'player4', 7, 'player3', 3, 'player5', 0]
This function yields:
[
{ id: 'player1', score: 13 },
{ id: 'player2', score: 11 },
{ id: 'player4', score: 7 },
{ id: 'player3', score: 3 },
{ id: 'player5', score: 0 }
]
Here is another one to transform the result into a two-dimensional array:
result.reduce(function (a, c, i) {
var idx = i / 2 | 0;
if (i % 2) {
a[idx].push(c);
} else {
a[idx] = [c];
}
return a;
}, []);
which produces the following array:
[
[ 'player1', 13 ],
[ 'player2', 11 ],
[ 'player4', 7 ],
[ 'player3', 3 ],
[ 'player5', 0 ]
]
One line lambda version:
result.reduce((a, c, i) => i % 2 ? (a[i / 2 | 0].data = c, a) : (a[i / 2 | 0] = { id: c }, a), []);
Vanilla JS reduce works well here.
const result = [
'player:522',
'19685',
'player:164',
'19594',
'player:807',
'19171',
'player:694',
'19165',
'player:905',
'19108',
'player:859',
'19087',
'player:432',
'18973',
'player:515',
'18831',
'player:163',
'18750',
'player:4',
'18552'
]
const map = result.reduce((map, k, i, res) => {
if (i % 2 !== 0) {
map[res[i - 1]] = Number(k);
}
return map;
}, {})
map is now:
{
'player:522': 19685,
'player:164': 19594,
'player:807': 19171,
'player:694': 19165,
'player:905': 19108,
'player:859': 19087,
'player:432': 18973,
'player:515': 18831,
'player:163': 18750.65468,
'player:4': 18552
}
var data = []
results.map((result, index) => {
if (index % 2 == 0) {
data.push(results[index] = { player: results[index], score: results[index+1] })
}
})
console.log(data)

Resources