display only value fields from the msg.payload in node red - javascript

I am working on node red (SNMP).
When I deploy, I have the output below:
[ { "oid": "1.3.6.1.2.1.10.21.1.2.1.1.2.1.26", "type": 2, "value":
104, "tstr": "Integer" }, { "oid": "1.3.6.1.2.1.10.21.1.2.1.1.2.2.27", "type": 2, "value": 104,
"tstr": "Integer" }, { "oid": "1.3.6.1.2.1.10.21.1.2.1.1.2.10.28",
"type": 2, "value": 1, "tstr": "Integer" }, { "oid":
"1.3.6.1.2.1.10.21.1.2.1.1.2.11.29", "type": 2, "value": 1, "tstr":
"Integer" }, { "oid": "1.3.6.1.2.1.10.21.1.2.1.1.2.12.30", "type": 2,
"value": 1, "tstr": "Integer" }, { "oid":
"1.3.6.1.2.1.10.21.1.2.1.1.2.13.31", "type": 2, "value": 1,
"tstr": "Integer" }, { "oid": "1.3.6.1.2.1.10.21.1.2.1.1.2.14.32",
"type": 2, "value": 101, "tstr": "Integer" }, { "oid":
"1.3.6.1.2.1.10.21.1.2.1.1.2.15.38", "type": 2, "value": 1,
"tstr": "Integer" }, { "oid": "1.3.6.1.2.1.10.21.1.2.1.1.2.100.39",
"type": 2, "value": 101, "tstr": "Integer" }, { "oid":
"1.3.6.1.2.1.10.21.1.2.1.1.2.101.40", "type": 2, "value": 101,
"tstr": "I ....
so I want to display all of the values from this output (104, 104, 1, 1 ....)
I am writing this function:
for(var i =0; i<Object.keys(msg.payload).length;i++)
{
msg.payload+=msg.payload[Object.keys(msg.payload)[i]].value;
}
return msg;
but I have an error:
TypeError: Object.keys called on non-object
any idea?

The problem is that your for loop is modifying msg.payload on each iteration - and because it is doing a += it is turning it into a String. That means the second time through the loop, msg.payload is no longer the object it was at the start so the Object.keys call fails.
You should build up your result in a new variable and set msg.payload at the end:
var result = [];
var keys = Object.keys(msg.payload);
for(var i =0; i<keys.length;i++)
{
result.push(msg.payload[keys[i]].value);
}
// At this point, result is an array of the values you want
// You can either return it directly with:
// msg.payload = result;
// or, if you want a string representation of the values as a
// comma-separated list:
// msg.payload = result.join(", ");
return msg;

Related

Compare value to get largest number in every object looping JavaScript

I have a problem with how to compare value to get largest number in more than one object.
For example i have 3 object (and this object can increment more than 3):
These each object saved in acc variable
[
{ "key": 1, "value": 1 },
{ "key": 1, "value": 3 },
{ "key": 1, "value": 6 },
]
[
{ "key": 2, "value": 2 },
{ "key": 2, "value": 5 },
{ "key": 2, "value": 9 },
]
[
{ "key": 3, "value": 1 },
{ "key": 3, "value": 2 },
{ "key": 3, "value": 3 },
]
First i get the last value from each object with console.log(acc[acc.length - 1].value);
and it will print:
6
9
2
Then i don't know how to compare the numbers? And get result:
{ "key": 2, "value": 9 }
I have try console.log(Math.max(acc[acc.length - 1].value));, but its not working because that number is not inside one array.
This is screenshot if i log console.log(acc)
First merge all the nested objects by .flat() and perform .reduce() operation on them. in every iteration look b.value is greater than the object value of accumulator a.value, if it's the case we need to update the object of the accumulator a.
const arr = [[ { "key": 1, "value": 1 }, { "key": 1, "value": 3 }, { "key": 1, "value": 6 }, ], [ { "key": 2, "value": 2 }, { "key": 2, "value": 5 }, { "key": 2, "value": 9 }, ], [ { "key": 3, "value": 1 }, { "key": 3, "value": 2 }, { "key": 3, "value": 3 }, ]];
console.log(arr.flat().reduce((a,b)=>(b.value > a.value ? b : a)));
New requirement:
const arr = [[
{ "key": 1, "value": 1 },
{ "key": 1, "value": 3 },
{ "key": 1, "value": 6 },
{ "key": 3, "value": 6 },
],
[
{ "key": 2, "value": 2 },
{ "key": 2, "value": 5 },
{ "key": 2, "value": 9 },
],
[
{ "key": 3, "value": 1 },
{ "key": 3, "value": 2 },
{ "key": 3, "value": 3 },
]];
let results = [{key: -1, value: -1}]; //initial value I assume data don't have a value less than -1
arr.forEach((item) => { //Simulating your current situation
item.forEach(it => { //here we get an array in each iteration
if (it.value > results[0].value) {
results = [it];
}
else if (it.value === results[0].value) {
results.push(it);
}
});
});
console.log(results);

How can i merge an array of objects in Nodejs with underscore

In my case i have a 2 db queries which are objects, one which returns all possible items which consists of a key and name field and then the other is a object which has the key, name and value field. What i am trying to do is to merge both objects where object 1 is the main object and object 2 should be merged into it.
What i ideally want is to return all items in Data2 with the value field merged into data2 and 0 if there is no data in data 1. if thats not possible i would be ok with no value in items in data 2 but i get even a strange result for that.
Fyi i am using underscore
const data1 = [
{
"count": 2,
"key": "c28f7ead-d87b-4ad5-b6b3-1f204b013b50",
"name": "Notes Written"
},
{
"count": 1,
"key": "d0181c74-22a9-4f99-9cc9-df3467c51805",
"name": "Pop-Bys Delivered"
},
{
"count": 2,
"key": "90d142ea-6748-4781-b2b9-4f05aab12956",
"name": "Database Additions"
},
{
"count": 1,
"key": "723e95dd-8c47-48ed-b9c3-1b010b092a1b",
"name": "Referals Given"
}
]
const data2 = [
{
"key": "8646ec5d-7a72-49bd-9a68-cf326d1c4a14",
"name": "Calls Made"
},
{
"key": "c28f7ead-d87b-4ad5-b6b3-1f204b013b50",
"name": "Notes Written"
},
{
"key": "d0181c74-22a9-4f99-9cc9-df3467c51805",
"name": "Pop-Bys Delivered"
},
{
"key": "90d142ea-6748-4781-b2b9-4f05aab12956",
"name": "Database Additions"
},
{
"key": "723e95dd-8c47-48ed-b9c3-1b010b092a1b",
"name": "Referals Given"
},
{
"key": "0f054686-ef13-4993-ac5b-f640ceeaaa8d",
"name": "Referals Received"
}
]
console.log(_.extend( data2, data1 ))
Here is a Replit example Sample Code
Using reduce, iterate over data1 while updating a Map of key-count pairs
Using each, iterate over data2 and set the value to the value of the key from the map, or 0 if it doesn't exist
const
data1 = [ { "count": 2, "key": "c28f7ead-d87b-4ad5-b6b3-1f204b013b50", "name": "Notes Written" }, { "count": 1, "key": "d0181c74-22a9-4f99-9cc9-df3467c51805", "name": "Pop-Bys Delivered" }, { "count": 2, "key": "90d142ea-6748-4781-b2b9-4f05aab12956", "name": "Database Additions" }, { "count": 1, "key": "723e95dd-8c47-48ed-b9c3-1b010b092a1b", "name": "Referals Given" } ],
data2 = [ { "key": "8646ec5d-7a72-49bd-9a68-cf326d1c4a14", "name": "Calls Made" }, { "key": "c28f7ead-d87b-4ad5-b6b3-1f204b013b50", "name": "Notes Written" }, { "key": "d0181c74-22a9-4f99-9cc9-df3467c51805", "name": "Pop-Bys Delivered" }, { "key": "90d142ea-6748-4781-b2b9-4f05aab12956", "name": "Database Additions" }, { "key": "723e95dd-8c47-48ed-b9c3-1b010b092a1b", "name": "Referals Given" }, { "key": "0f054686-ef13-4993-ac5b-f640ceeaaa8d", "name": "Referals Received" } ];
const map = _.reduce(
data1,
(map, { key, count }) => map.set(key, count),
new Map
);
_.each(
data2,
e => e.value = map.get(e.key) || 0
);
console.log(data2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.1/underscore-min.js" integrity="sha512-ZuOjyqq409+q6uc49UiBF3fTeyRyP8Qs0Jf/7FxH5LfhqBMzrR5cwbpDA4BgzSo884w6q/+oNdIeHenOqhISGw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

how to modify properties of an nested object?

I have the following nested object and I need to leave the "alias" property blank and the "group" property set to true for all "entries" and "exits". I also need to delete the whole "parameters" object.
Would there be a way to do it all in one function? I've tried to apply the delete Object method but it doesn't work as it's an indexed object.
{
"1": {
"x": 114,
"y": 135,
"properties": {
"id": 1,
"entries": {
"entry_0": {
"id": 1,
"alias": "do",
"group": false
}
},
"exits": {
"exit_0": {
"id": 1,
"alias": "re",
"group": false
}
},
"parameters": {
"parameter_0": {
"id": 3,
"group": false
}
},
"order": 1
}
},
"2": {
"x": 700,
"y": 104,
"properties": {
"id": 1
"entries": {
"entry_0": {
"id": 1
"alias": "do"
"group": false
}
},
"exits": {
"exyt_0": {
"id": 1
"alias": "re"
"group": false
}
},
"parameters": {
"parameter_0": {
"id": 3
"alias": "mi"
"group": false
}
},
"order": 2
}
}
}
the desired nested object would be the following
{
"1": {
"x": 114,
"y": 135,
"properties": {
"id": 1,
"entries": {
"entry_0": {
"id": 1,
"alias": "",
"group": true
}
},
"exits": {
"exit_0": {
"id": 1,
"alias": "",
"group": true
}
},
"order": 1
}
},
"2": {
"x": 700,
"y": 104,
"properties": {
"id": 1
"entries": {
"entry_0": {
"id": 1
"alias": ""
"group": true
}
},
"exits": {
"exyt_0": {
"id": 1
"alias": ""
"group": true
}
},
"order": 2
}
}
}
what I've tried is the following, managing to delete the "parameters" object but I can't access the "label" property of each "entry" and "exit
const nedtedObjectsValues = Object.values(nestedObjects);
for (object of nedtedObjectsValues) {
delete object.properties.parameters;
}
if anyone can give me an idea of how to approach this function.
Thank you in advance.
In JavaScript, to reference numeric object properties, you need to use the square brackets syntax:
object.1 // bad
object[1] // good
You can delete numeric property like this:
delete object[1];

How to remove parent fields in json variable and convert it to json in javascript or jquery

Am working on some project which has lot of objects involvement. I have below requirement in javascript or jQuery.
I have below object:
var dataset = {
"d0": { "id": 0, "name": "Housing", "value": 18 },
"d1": { "id": 1, "name": "Travel", "value": 31.08 },
"d2": { "id": 2, "name": "Restaurant", "value": 64 },
"d3": { "id": 3, "name": "Bank", "value": 3 },
"d4": { "id": 4, "name": "Movies", "value": 10 }
};
How can I remove parent fields and make it as object like below ?
var d= [
{ "id": 0, "name": "Housing", "value": 18 },
{ "id": 1, "name": "Travel", "value": 31.08 },
{ "id": 2, "name": "Restaurant", "value": 64 },
{ "id": 3, "name": "Bank", "value": 3 },
{ "id": 4, "name": "Movies", "value": 10 }
]
After doing this, I wanted to pass this object to a javascript function which manipulates the value of this variable d.
if(value >= 10 && value <= 20) {
d[index].value = 7;
}
if(value >= 20 && value <= 40) {
d[index].value = 8;
}
Updated object should look like :
var d= [
{ "id": 0, "name": "Housing", "value": 7 },
{ "id": 1, "name": "Travel", "value": 8 },
{ "id": 2, "name": "Restaurant", "value": 64 },
{ "id": 3, "name": "Bank", "value": 3 },
{ "id": 4, "name": "Movies", "value": 10 }
]
I tried looping to the dataset using for loop, but couldn't achieve my requirement.
Any help?
Use Array#forEach with Object.keys() to iterate over object.
var dataset = {
"d0": { "id": 0, "name": "Housing", "value": 18 },
"d1": { "id": 1, "name": "Travel", "value": 31.08 },
"d2": { "id": 2, "name": "Restaurant", "value": 64 },
"d3": { "id": 3, "name": "Bank", "value": 3 },
"d4": { "id": 4, "name": "Movies", "value": 10 }
};
// Declare resulting empty array
var d = [];
// Get object keys and iterate over them
Object.keys(dataset).forEach(function (key) {
// Get the value from the object
var value = dataset[key].value;
// Update values if in the range
if(value >= 10 && value <= 20) {
dataset[key].value = 7;
} else if(value > 20 && value <= 40) {
dataset[key].value = 8;
}
// Push the updated(or not) value in the array
d.push(dataset[key]);
});
console.log(d);
document.getElementById('result').innerHTML = JSON.stringify(d, null, 4);
<pre id="result"></pre>
Just map it with Array.prototype.map method:
var dataset = {
"d0": { "id": 0, "name": "Housing", "value": 18 },
"d1": { "id": 1, "name": "Travel", "value": 31.08 },
"d2": { "id": 2, "name": "Restaurant", "value": 64 },
"d3": { "id": 3, "name": "Bank", "value": 3 },
"d4": { "id": 4, "name": "Movies", "value": 10 }
};
var d = Object.keys(dataset).map(function(key) {
var obj = dataset[key];
if (obj.value >= 10 && obj.value <= 20) {
obj.value = 7;
}
else if (obj.value >= 20 && obj.value <= 40) {
obj.value = 8;
}
return obj;
});
document.write('<pre>' + JSON.stringify(d, null, 4) + '</pre>');
You can do it this way:
var dataset = {
"d0": { "id": 0, "name": "Housing", "value": 18 },
"d1": { "id": 1, "name": "Travel", "value": 31.08 },
"d2": { "id": 2, "name": "Restaurant", "value": 64 },
"d3": { "id": 3, "name": "Bank", "value": 3 },
"d4": { "id": 4, "name": "Movies", "value": 10 }
};
First remove the string keys:
var d = [];
for(var k in dataset){
d.push(dataset[k]);
}
Then iterate over resulting array modifying it accordingly:
for(var k in d){
var value = d[k]['value'];
if(value>=10 && value<=20){
d[k].value=7;
}
if(value>=20 && value<=40){
d[k].value=8;
}
}
This gives the resuls you're looking for:
var dataset = {
"d0": { "id": 0, "name": "Housing", "value": 18 },
"d1": { "id": 1, "name": "Travel", "value": 31.08 },
"d2": { "id": 2, "name": "Restaurant", "value": 64 },
"d3": { "id": 3, "name": "Bank", "value": 3 },
"d4": { "id": 4, "name": "Movies", "value": 10 }
};
var d = Object.keys(dataset).map(function(key) {
var v = dataset[key].value;
if (v >= 10 && v <= 20) dataset[key].value = 7;
else if (v > 20 && v <= 40) dataset[key].value = 8;
return dataset[key];
});
try this,
function datasetToArrOfObj(dataset){
var rslt = [];
for (var key in dataset) {
if (dataset.hasOwnProperty(key)) {
rslt.push(dataset[key]);
}
}
return rslt;
}

Underscorejs:How to create a new object by combining values from two objects?

I came across the following scenario
var obj1= [
{
"id": 97,
"name": "Sample1",
"classId": 751,
"gradeId": 1,
"studentId": 1
},
{
"id": 98,
"name": "Sample2",
"classId": 751,
"gradeId": 1,
"studentId": 2
},
{
"id": 97,
"name": "Sample1",
"classId": 751,
"gradeId": 2,
"studentId": 3
},
{
"id": 98,
"name": "Sample2",
"classId": 751,
"gradeId": 2,
"studentId": 4
}
]
Now ,If the id's are same,I need to combine the identical object values in the following form
var obj2=[
{
"id": 97,
"name": "Sample1",
"classId": 751,
"rating":[
{
"gradeId": 1,
"studentId": 1
}
{
"gradeId": 2,
"studentId": 3
}
]
},
{
"id": 98,
"name": "Sample2",
"classId": 751,
"rating":[
{
"gradeId": 1,
"studentId": 2
}
{
"gradeId": 2,
"studentId": 4
}
]
}
]
I am looping through all the objects and ifnthe id's are same I am creating a new object with the combined values,which i feel a little bit elaborated
Can i achieve this through underscore js in a more abstract way?
_.groupBy will do what you want, then use pick/omit to map the groups to the nested objects as you want them:
var obj2 = _.map(_.groupBy(obj1, "id"), function(group) {
var o = _.omit(group[0], "gradeId", "studentId");
o.rating = _.map(group, function(s) {
return _.pick(s, "gradeId", "studentId");
});
return o;
});

Categories

Resources