Help with JSON structure - javascript

I have the following javascript which I need to make dynamic.
data.addRows(2);
data.setValue(0, 0, 'name goes here');
data.setValue(0, 1, value 1 goes here);
data.setValue(0, 2, value 2 goes here);
data.setValue(1, 0, 'name goes here');
data.setValue(1, 1, value 1 goes here);
data.setValue(1, 2, value 2 goes here);
I guess a loop is the best way to go forward:
I have come up with the following json structure:
[
{"User1":{"value1": 50.00,"value2": "100"}},
{"User2":{"value1": 10.00,"value2": "20"}},
{"User3":{"value1": 10.00,"value2": "20"}},
{"User4":{"value1": 10.00,"value2": "20"}},
{"User5":{"value1": 20.00,"value2": "40"}}
]
I think this structure needs improving. Can someone please suggest a better structure to make it very easy for me to extract the data I want to extract from this?

var dataset = [
{uid: 'user1', value1: 50.00, value2: 100},
{uid: 'user2', value1: 10.00, value2: 20},
];
That way you can do data.length to figure out how many values you have and you can loop a bit easier. For example:
for(i = 0; i < dataset.length; i++) {
console.log(data[i].uid);
}
Using your example:
data.addRows(2);
var l = dataset.length, i, x = 0, y = 0;
for(i = 0; i < l; i++) {
data.setValue(y, x, dataset[i].uid); x++;
data.setValue(y, x, dataset[i].value1); x++;
data.setValue(y, x, dataset[i].value2); x=0;
y++;
}

I don't see that you could make it anymore simple, unless there's something special about the data that would allow repeated parts to be separated out in some fashion.

Try something like:
{"users": [
{"value1": 50, "value2": 100},
{"value1": 10, "value2": 20},
{"value1": 10, "value2": 20},
{"value1": 10, "value2": 20},
{"value1": 20, "value2": 40}
]}
Or, if you want to have your users have IDs:
{"users": {
"userId1": {"value1": 50, "value2": 100},
"userId2": {"value1": 10, "value2": 20},
"userId3": {"value1": 10, "value2": 20},
"userId4": {"value1": 10, "value2": 20},
"userId5": {"value1": 20, "value2": 40}
}}
Remember, all numbers in JavaScript are floating-point numbers.

I think you can try something like this, the idea is from ColdFusion SerializeJson()
I assume your data is like a table
user value1 value2
------------------------------------
user1 50 100
user2 10 20
...
the json structure is
{"COLUMNS":["USER","VALUE1","VALUE2"],"DATA":[["user1",50.0,100.0],["user2",10.0,20.0]]}
more clear reading
{
"COLUMNS":
[
"USER",
"VALUE1",
"VALUE2"
],
"DATA":
[
[
"user1",
50.0,
100.0
],
[
"user2",
10.0,
20.0
]
]
}
with this structure, we know that every varname.DATA[index][0] is refers to USER

Check this link for json encoding
And for now your json value should be encoded like this
{"id":8,"heading":"heading goes here","content":"<p>content goes here<\/p>"}
Sorry not for you....

Related

Re-format an array of objects in Javascript in custom array format by property id

I am having trouble reformatting an Object array in Javascript. I have an array that looks like this:
[
{
"deviceid": 42,
"x": "2022-03-26T00:00:18",
"y": 17.8,
},
{
"deviceid": 42,
"x": "2022-03-26T00:01:18",
"y": 17.8,
},
{
"deviceid": 43,
"x": "2022-03-26T00:02:18",
"y": 17.8,
{
"deviceid": 43,
"x": "2022-03-26T00:02:18",
"y": 17.8,
}]
I want to re-shape it so the new form will be one record per device id and all x and y values in the same row.
[
{
"deviceid": 42,
"x": ["2022-03-26T00:00:18","2022-03-27T00:00:18"],
"y": [17.8, 15.6],
},
{
"deviceid": 43,
"x": ["2022-03-26T00:01:18","2022-03-27T00:00:18"],
"y": [17.8, 19.1],
}]
How can I make this happen?
You can use reduce() to do the reduction of your values using a JavaScript object. After the reduction get the values of the object using Object.values().
const data = [
{
deviceid: 42,
x: "2022-03-26T00:00:18",
y: 17.8,
},
{
deviceid: 42,
x: "2022-03-26T00:01:18",
y: 15.6,
},
{
deviceid: 43,
x: "2022-03-26T00:02:18",
y: 17.8,
},
{
deviceid: 43,
x: "2022-03-26T00:02:18",
y: 19.1,
},
];
const result = data.reduce((devices, device) => {
// check if we have encountered this decive before using the deviceId
if (!devices.hasOwnProperty(device.deviceid)) {
// we have not: create an key-value pair using device ID as key and device info as value
// use an array for x and y
devices[device.deviceid] = {
deviceId: device.deviceid,
x: [device.x],
y: [device.y],
};
} else {
// we have seen this device before
// get the device value using the key (deviceId) and push new x and y values to it
const curDev = devices[device.deviceid];
curDev.x.push(device.x);
curDev.y.push(device.y);
}
// return JS object of devices for next iteration/ result
return devices;
}, {});
console.log(Object.values(result));
Please note: I think the input you have provided in your question contains some errors probably from copy/ pasting as the expected output contains values that are not in the input at all. I have changed values of y in the input to show you that output is actually what you expect.

JQuery JSON [object Object]

I have a JSON that is structured like so:
students.json (UPDATED FROM COMMENTS BELOW)
{
Cindy: { age: 9, m1: 80, m2: 90, s1: 90, s2: 100 },
Mark: { age: 12, m1: 80, m2: 90, s1: 90, s2: 100 },
Jeff: { age: 8, m1: 90, m2: 90, s1: 90, s2: 95 },
Ann: { age: 11, m1: 90, m2: 60, s1: 90, s2: 100 },
Jason: { age: 5, m1: 95, m2: 30, s1: 90, s2: 185 },
Harvey: { age: 10, m1: 100, m2: 70, s1: 90, s2: 100 },
Mike: { age: 9, m1: 100, m2: 80, s1: 90, s2: 82 },
Ross: { age: 9, m1: 88, m2: 90, s1: 90, s2: 100 },
};
In my javascript code I'm importing multiple JSON using JQuery.
var objects = {};
$.getJSON("object1.json", function (data) {
objects = data;
});
var students = {};
$.getJSON("info.json", function (data) {
students = data;
});
// .......
function function1(object) {}
function function2(object) {}
// .......
function main() {
function1(object1);
function2(object2);
}
When I inspect the imported object students, I get:
[object Object]:{
"Cindy" : {"age": 9, "m1":80, "m2":90, "s1":90 , "s2":100},
"Mark" : {"age": 12, "m1":80, "m2":90, "s1":90 , "s2":100},
"Jeff" : {"age": 8, "m1":90, "m2":90, "s1":90 , "s2":95},
"Ann" : {"age": 11, "m1":90, "m2":60, "s1":90 , "s2":100},
"Jason" : {"age": 5, "m1":95, "m2":30, "s1":90 , "s2":185},
"Harvey" : {"age": 10, "m1":100, "m2":70, "s1":90 , "s2":100},
"Mike" : {"age": 9, "m1":100, "m2":80, "s1":90 , "s2":82},
"Ross" : {"age": 9, "m1":88, "m2":90, "s1":90 , "s2":100}
}
It appears that this [object Object] is now a "key"?
UPDATED:
My original question was from the thought that this was preventing me from accessing the object, but that was not my problem. It operates as expected. I can access students.Cindy.age //9 just fine. My problem is that the getJSON happens AFTER the function call so "undefined" objects are being passed into the functions. I need the html to load first as some of the javascript functions manipulate the html page.
you can access like the following 2 types
students.Cindy.age
students['Cindy']['age']
Fix the issues with missing commas around the array properties and assign the outer object to a variable. Then you can use bracket/dot notation to access the properties. You should also fix the nested objects indentation to make your code easier to read.
Check out this example.
var data = {
"Cindy": {
"age": 9,
"m1": 80,
"m2": 90,
"s1": 90,
"s2": 100
},
"Mark": {
"age": 12,
"m1": 80,
"m2": 90,
"s1": 90,
"s2": 100
}
}
Now the following accesses the data:
alert(data["Cindy"].age);
alert(data["Mark"].m1);
There are multiple issues. $.getJSON("info.json" these are async in nature. Instead of $.getJSON, u can use fetch It has better support. Using fetch requests. Promise.all wait for the responses then you can perform the task.
$(function () {
function function1(objects) {
console.log(objects)
}
function function2(students) {
console.log(students.Cindy.age)
console.log(students.Cindy.m1)
}
/*
var objects = {};
$.getJSON("object1.json", function (data) { // these are async in nature
objects = data;
});
var students = {};
$.getJSON("info.json", function (data) { // these are async in nature
students = data;
});
*/
// instead of $.getJSON, u can use `fetch` It has better support
const promises = [fetch("object1.json").then(res => res.json()) , fetch("info.json").then(res => res.json()]
Promise.all(promises).then((results) => {
const [objects, students] = results// data is avaible here,
function1(objects); // do something with objects
function2(students);// do something with students
})
})();

Using a variable in an JSON query

I am trying to write a function that can take a field name as an argument and return an array of corresponding values from a bit of JSON.
Example object:
var myObject = [
{"x": 10, "y": 10},
{"x": 20, "y": 10},
{"x": 20, "y": 20},
{"x": 10, "y": 20}
];
My function looks something like this:
function getValues(desiredValue) {
var values = [];
for (i = 0; i < myObject.length; i++) {
values[i] = myObject[i].desiredValue;
}
return values;
}
getValues(x);
Ideally, I would have the argument x passed to the getValues which, instead of looking for a field name called desiredValue would look for a field name called x.
The returned array should look like this:
[10,20,20,10]
As the problem with this code is obvious, how can I get the desired result?
Also, I am trying to avoid unnecessary dependencies, so please don’t give me any JQuery unless absolutely necessary.
You can use map() to return desired result.
var myObject = [
{"x": 10, "y": 10},
{"x": 20, "y": 10},
{"x": 20, "y": 20},
{"x": 10, "y": 20}
];
function getValues(desiredValue) {
return myObject.map(e => e[desiredValue]);
}
console.log(getValues('x'))
You actually need to parse the given JSON string (not the array that you have given here) by using JSON.parse(). See: http://jsbin.com/kevoqe/edit?js,console
a simple utility
//also accepts a path like "foo.bar.baz"
//returns undefined if path can't be resolved
function fetch(path){
var keys = path.split(".");
return function( target ){
for(var t = target, i = 0; i < keys.length; t = t[ keys[ i++ ] ])
if(t == null) return void 0;
return t;
}
}
and it's usage
var myObject = [
{"x": 10, "y": 10},
{"x": 20, "y": 10},
{"x": 20, "y": 20},
{"x": 10, "y": 20}
];
var result = myObject.map( fetch("y") );
this version is a bit more flexible than one hardwired with Array.map() because it can easily be composed with other functions.
Although, especially in this particular case, this already is a little bit of overkill. here you can easily write:
var result = myObject.map(pt => pt.y);
you can't get any shorter and simpler. Or if for some reason the property really is dynamic, you'll have some variable containing it:
var dynamicPropertyName = "y";
//...
var result = myObject.map(pt => pt[ dynamicPropertyName ]);
Use array map method to do manipulation in an array of objects.
Try this code :
var myObject = [
{"x": 10, "y": 10},
{"x": 20, "y": 10},
{"x": 20, "y": 20},
{"x": 10, "y": 20}
];
var output = getValues("x");
console.log(output);
function getValues(desiredValue) {
return myObject.map(function(item) {
return item[desiredValue];
});
}
Output :
Working fiddle : https://jsfiddle.net/ffyjyzjb/

Dynamically fill multidimensional array with arrays

I've been doing some research and am not getting anywhere. I have a situation where I need an array to contain a possibly variable number of arrays. Based on the example below, do you have any ideas?
var masterArray = [];
function PrepData(inVal) {
var amt = inVal.split("|");
for (var i = 0; i < amt.length; i++) {
// !!!Trouble area!!!
masterArray[i].push = amt[i];
};
}
What I'm doing is feeding 12 months' worth of data into this function, so PrepData runs 12 times each time I activate the calling function. The variable inVal can contain something like "9|9|0" or "9|123|470|1500|13". What I'm looking to do is split the incoming value on the pipe and store the results in amt. Then I want to feed each value from amt into individual arrays within masterArray. The good news is that inVal's length is constant once the first value is in, so if the first of 12 iterations splits into 3 pieces, the other 11 will also. To lay it out, here's what I would expect a typical run to produce given this input:
Oct: "1|2|1300"
Nov: "1|3|1400"
Dec: "2|5|1450"
Jan: "3|6|1900"
Feb: "4|8|2015"
Mar: "4|8|2020"
Apr: "19|38|3200"
May: "30|42|3500"
Jun: "32|50|5000"
Jul: "48|72|6300"
Aug: "50|150|7500"
Sep: "80|173|9000"
Once all twelve run through PrepData, I should have an array that contains this:
masterArray[0] == {1, 1, 2, 3, 4, 4, 19, 30, 32, 48, 50, 80} // All the numbers from the first section
masterArray[1] == {2, 3, 5, 6, 8, 8, 38, 42, 50, 72, 150, 173} // All the numbers from the second section
masterArray[2] == {1300, 1400, 1450, 1900, 2015, 2020, 3200, 3500, 5000, 6300, 7500, 9000} // All the numbers from the third section
If each month contained a string with 5 sections, then masterArray would need to be able to go from [0] to [4], and so on. The trouble area above isn't working, so I'm obviously missing something, but don't know what that might be.
Here is the updated code
var masterArray = [];
function PrepData(inVal){
var amt = inVal.split("|");
for (i in amt) {
if(typeof masterArray[i] == 'undefined'){
masterArray[i] = [];
}
masterArray[i].push(amt[i]);
}
}
There is a need to check first if an array is defined in each index in masterArray. If it's not defined then you need to initialize it to a blank array. Then you can push the splited value and you get the same result
masterArray[0] == {1, 1, 2, 3, 4, 4, 19, 30, 32, 48, 50, 80}
masterArray[1] == {2, 3, 5, 6, 8, 8, 38, 42, 50, 72, 150, 173}
masterArray[2] == {1300, 1400, 1450, 1900, 2015, 2020, 3200, 3500, 5000, 6300, 7500, 9000}
Here is a demo in js fiddle

JQuery $.extend() recursivity peculiarity

I want to extend an object in a specific position in an array, without having to send the whole array again.
Example:
You start out with the array like this:
sensors = [{value: 10}, {value: 20}];
Now say I want to change the value of the second sensor, I can do this in jQuery:
newSensorValue = {1: {value:30}};
$.extend(true, sensors, newSensorValue);
// sensors = [{value: 10}, {value: 30}];
However, if the array is not directly the object that is merged, this does not work:
node = {x: 10, y: 10, node_id: 1, sensors: [
{sensor_id: 1, value: 10},
{sensor_id: 2, value: 20}
]};
newNodeData = {sensors: {
1: {value:30}
}};
$.extend(true, node, newNodeData);
// node = {x: 10, y: 10, node_id: 1, sensors: {
// 1: {value:30}
// }};
Why does $.extend() suddenly behave differently if the array is nested in an object?
My own solution would be to create an array of empty objects, only giving the object that I want to change the "value" attribute, like:
newNodeData = {sensors: [
{}, {value: 30}
]};
Since this seems rather ugly, is there a better way to do this?
I would prefer to keep the sensors attribute an array, since I like to use forEach to go through each sensor quickly.
EDIT: forgot to mention that if I do
$.extend(true, node.sensors, newNodeData.sensors);
It works the same as in the first example (i.e. it works)
You could leave the element empty when you don't want to change it.
node = {x: 10, y: 10, node_id: 1, sensors: [
{sensor_id: 1, value: 10},
{sensor_id: 2, value: 20}
]};
newNodeData = {sensors: [,{value:30}]};
$.extend(true, node, newNodeData);

Categories