Create Nested JSON object Javascript - javascript

Hello I want to create a JSON Object for storage resources in a post request in java script I have an input array value disk sizes for example below:
request1
input = [10, 20, 30]
"storageResources": [
{
"stats": [
{
"name": "diskSize",
"units": "GB",
"value": 10
},
{
"name": "diskIopsConsumed",
"value": 0
},
{
"name": "diskConsumedFactor",
"value": 1
}
]
},
{
"stats": [
{
"name": "diskSize",
"units": "GB",
"value": 20
},
{
"name": "diskIopsConsumed",
"value": 1
},
{
"name": "diskConsumedFactor",
"value": "NaN"
}
]
},
{
"stats": [
{
"name": "diskSize",
"units": "GB",
"value": 30
},
{
"name": "diskIopsConsumed",
"value": 0
},
{
"name": "diskConsumedFactor",
"value": 1
}
]
},
],
request2:
input [10,20]
"storageResources": [
{
"stats": [
{
"name": "diskSize",
"units": "GB",
"value": 10
},
{
"name": "diskIopsConsumed",
"value": 0
},
{
"name": "diskConsumedFactor",
"value": 1
}
]
},
{
"stats": [
{
"name": "diskSize",
"units": "GB",
"value": 20
},
{
"name": "diskIopsConsumed",
"value": 1
},
{
"name": "diskConsumedFactor",
"value": "NaN"
}
]
}
],
Is the best way to do this with a function or can you send it by properties?

Use Array.prototype.map to return a modified response
$$text.oninput = evt => {
let json = JSON.parse($$text.value)
let result = json.storageResources.map(resource =>
resource.stats.find(e => e.name == 'diskSize').value
)
console.log(result)
}
$$text.oninput()
<textarea id="$$text">{"storageResources":[{"stats":[{"name":"diskSize","units":"GB","value":10},{"name":"diskIopsConsumed","value":0},{"name":"diskConsumedFactor","value":1}]},{"stats":[{"name":"diskSize","units":"GB","value":20},{"name":"diskIopsConsumed","value":1},{"name":"diskConsumedFactor","value":"NaN"}]},{"stats":[{"name":"diskSize","units":"GB","value":30},{"name":"diskIopsConsumed","value":0},{"name":"diskConsumedFactor","value":1}]}]}</textarea>

Related

javascript split array in two arrays

I am trying to split this array into two different arrays using the values inside the first array.
This is my initial array:
"carList": [
{
"brand": [
{
"model": [
{ "motor": { "id": 1 }, "color": 10 },
{ "motor": { "id": 2 }, "color": 20 },
{ "motor": { "id": 3 }, "color": 30 },
{ "motor": { "id": 4 }, "color": 40 }
]
}
]
},
{ "brand": [{ "model": [{ "size": 400 }] }] },
{ "brand": [{ "model": [{ "size": 500 }] }] }
],
The first array must contain the model with the motor and the colors. The second should only contain the brand with the size (I can have an indeterminate number of brands).
I would like this as an output:
"carList": [
{
"brand": [
{
"model": [
{ "motor": { "id": 1 }, "color": 10 },
{ "motor": { "id": 2 }, "color": 20 },
{ "motor": { "id": 3 }, "color": 30 },
{ "motor": { "id": 4 }, "color": 40 }
]
}
]
},
],
"carList": [
{ "brand": [{ "model": [{ "size": 400 }] }] },
{ "brand": [{ "model": [{ "size": 500 }] }] }
],
When trying to split the array, I tried to create the array only with size, but I get the carList global:
const carList1 = carList.filter((x) =>
x.brand.filter((y) => y.model.filter((z) => z.size)
);
How I can split my array and get this output?
UPDATE
This is my more genral exemple test I can have many brand and model,
"carList": [
{
"brand": [
{
"model": [
{ "motor": { "id": 1 }, "color": 10 },
{ "motor": { "id": 2 }, "color": 20 },
{ "motor": { "id": 3 }, "color": 30 },
{ "motor": { "id": 4 }, "color": 40 }
]
},
{
"model": [
{ "motor": { "id": 1 }, "color": 11 },
{ "motor": { "id": 2 }, "color": 22 },
{ "motor": { "id": 3 }, "color": 33 },
{ "motor": { "id": 4 }, "color": 44 }
]
}
]
},
{ "brand": [
{
"model": [
{ "size": 400 },
]
},
{
"model": [
{ "size": 401 }
]
},
{ "brand": [{ "model": [{ "size": 500 }] }] }
],
This would be one way of doing it:
const data={"carList":[
{"brand":[{"model": [{ "motor": { "id": 1 }, "color": 10 },
{ "motor": { "id": 2 }, "color": 20 },
{ "motor": { "id": 3 }, "color": 30 },
{ "motor": { "id": 4 }, "color": 40 }]},
{"model": [{ "motor": { "id": 1 }, "color": 11 },
{ "motor": { "id": 2 }, "color": 22 },
{ "motor": { "id": 3 }, "color": 33 },
{ "motor": { "id": 4 }, "color": 44 }]}
]},
{"brand":[{"model": [{ "size": 400 }]},
{"model": [{ "size": 401 }]}]},
{"brand":[{"model": [{ "size": 500 }]}]}
]}
const [mo,si]=["motor","size"].map(p=>data.carList.filter(e=>
e.brand.find(b=>b.model.find(m=>m[p]))));
console.log(JSON.stringify(mo));
console.log(JSON.stringify(si));
I applied the snippet now to the updated data. The result arrays motor and sizes are calculated by applying a .filter() on the data array.
In this updated version of the script I assign a brand to the mo or si array if it somehow contains the property motor or size`.

ES6 Object Mapping

I was working on something but stuck at a point where I have inputs as -
var definition = [
{
"name": "objA",
"type": "object",
"items": [
{
"value": "",
"name": "A"
},
{
"value": "",
"name": "B"
},
{
"value": "",
"name": "C"
}
]
},
{
"name": "objX",
"type": "object",
"items": [
{
"value": "",
"name": "X"
},
{
"value": "",
"name": "Y"
},
{
"value": "",
"name": "Z"
}
]
}
];
var data = {
"objA": {
"A": "ValA",
"B": "ValB",
"C": "ValC"
},
"objX": {
"X": "ValX",
"Y": "ValY",
"Z": "ValZ"
}
};
const updateSchema = (data, definition) => {
definition.forEach((subDef) => {
var node = data[subDef.name];
subDef.items.forEach((sub)=> {
sub.value = node[sub.name]
});
});
return definition;
}
console.log(updateSchema(data,definition))
The output I need is
[
{
"name": "objA",
"type": "object",
"items": [
{
"value": "valA",
"name": "A"
},
{
"value": "valB",
"name": "B"
},
{
"value": "valC",
"name": "C"
}
]
},
{
"name": "objX",
"type": "object",
"items": [
{
"value": "valX",
"name": "X"
},
{
"value": "valY",
"name": "Y"
},
{
"value": "valZ",
"name": "Z"
}
]
}
]
But it gives the output as -
[
{
"name": "objA",
"type": "object",
"items": [
{
"value": "ValX",
"name": "A"
},
{
"value": "ValY",
"name": "B"
},
{
"value": "ValY",
"name": "C"
}
]
},
{
"name": "objX",
"type": "object",
"items": [
{
"value": "ValX",
"name": "X"
},
{
"value": "ValY",
"name": "Y"
},
{
"value": "ValZ",
"name": "Z"
}
]
}
]
I am not able to know where I am doing wrong.
I am using React with typescript. I need to perform the above operation based on some API response.
I am prepopulating some value in the form based on the API response.
Try:
subDef.items.forEach((sub)=> {
sub.value = node[sub.name].charAt(0).toLowerCase() + node[sub.name].slice(1);
});
https://jsfiddle.net/j8nwpf6m/

How to filter nested array in typescript?

I have a JSON as below
{
"Header": {
"Time": "2020-06-09T07:03:20-07:00",
"ReportName": "JournalReport",
"StartPeriod": "2020-06-09",
"EndPeriod": "2020-06-09",
"Currency": "USD",
"Option": [
{
"Name": "NoReportData",
"Value": "false"
}
]
},
"Columns": {
"Column": [
{
"ColTitle": "Date",
"ColType": "Date",
"MetaData": [
{
"Name": "ColKey",
"Value": "tx_date"
}
]
},
{
"ColTitle": "Transaction Type",
"ColType": "String",
"MetaData": [
{
"Name": "ColKey",
"Value": "txn_type"
}
]
},
{
"ColTitle": "Num",
"ColType": "String",
"MetaData": [
{
"Name": "ColKey",
"Value": "doc_num"
}
]
},
{
"ColTitle": "Name",
"ColType": "String",
"MetaData": [
{
"Name": "ColKey",
"Value": "name"
}
]
},
{
"ColTitle": "Memo/Description",
"ColType": "String",
"MetaData": [
{
"Name": "ColKey",
"Value": "memo"
}
]
},
{
"ColTitle": "Account",
"ColType": "String",
"MetaData": [
{
"Name": "ColKey",
"Value": "account_name"
}
]
},
{
"ColTitle": "Debit",
"ColType": "Money",
"MetaData": [
{
"Name": "ColKey",
"Value": "debt_home_amt"
}
]
},
{
"ColTitle": "Credit",
"ColType": "Money",
"MetaData": [
{
"Name": "ColKey",
"Value": "credit_home_amt"
}
]
}
]
},
"Rows": {
"Row": [
{
"ColData": [
{
"value": "0-00-00"
},
{
"value": "",
"id": "559"
},
{
"value": ""
},
{
"value": "",
"id": ""
},
{
"value": ""
},
{
"value": "California Department of Tax and Fee Administration Payable",
"id": "678"
},
{
"value": ""
},
{
"value": "1.25"
}
],
"type": "Data"
},
{
"ColData": [
{
"value": "0-00-00"
},
{
"value": "",
"id": "559"
},
{
"value": ""
},
{
"value": "",
"id": ""
},
{
"value": ""
},
{
"value": "California Department of Tax and Fee Administration Payable",
"id": "678"
},
{
"value": ""
},
{
"value": ".10"
}
],
"type": "Data"
},
{
"Summary": {
"ColData": [
{
"value": ""
},
{
"value": ""
},
{
"value": ""
},
{
"value": ""
},
{
"value": ""
},
{
"value": ""
},
{
"value": "31.75"
},
{
"value": "31.75"
}
]
},
"type": "Section"
},
{
"ColData": [
{
"value": "0-00-00"
},
{
"value": "",
"id": "567"
},
{
"value": ""
},
{
"value": "",
"id": ""
},
{
"value": ""
},
{
"value": "Accounts Payable (A/P)",
"id": "676"
},
{
"value": "232.00"
},
{
"value": ""
}
],
"type": "Data"
}
]
}
}
I want to filter this array which matches Rows.Row[someindex].ColData[1].id == 567. Here id should match with second object of ColData array.
But after filtering i don't want to skip the records from resulting array those have Summary as Rows.Row[someindex].Summary. Summary records should be included in resulting array.
I have tried below code but it does not work because In Row.Row array Summary can be there instead of ColData at some indexs & also i want include Summary records in resulting array even if i have found the desired object.
function getResult(filterbY, objList) {
return objList.Rows.Row.filter(function(obj) {
return obj.ColData.some(function(item){
return item.id == filterbY;
});
});
}
Please help with the same ?
you need to include your summary in your filter function then,
function getResult(filterbY, objList) {
return objList.Rows.Row.filter(function(obj) {
if(obj.Summary){return true;}
return obj.ColData.some(function(item){
return item.id == filterbY;
});
});
}

d3 hierarchy ability to average children node values

I have a d3 visualization that has a JSON object similar to the following where I would like to average up the value of score on the lowest nodes and dynamically add that average to the parent node above...and so on. It doesn't look like d3 has an easy method to do this. What I'd like is to have the final JSON output look like the second example.
{
"name": "A1",
"children": [
{
"name": "B1",
"children": [
{
"name": "B1-C1",
"children": [
{
"name": "B1-C1-D1",
"children": [
{
"name": "B1-C1-D1-E1",
"value": 30,
"score": 0.8
},
{
"name": "B1-C1-D1-E2",
"value": 35,
"score": 0.5
}
]
},
{
"name": "B1-C1-D2",
"children": [
{
"name": "B1-C1-D2-E1",
"value": 31,
"score": 0.4
},
{
"name": "B1-C1-D2-E2",
"value": 23,
"score": 0.7
}
]
}
]
}
]
}
]
}
What I'd like the final JSON object to look like:
{
"name": "A1",
"scoreAvg": 0.625,
"children": [
{
"name": "B1",
"scoreAvg": 0.625,
"children": [
{
"name": "B1-C1",
"scoreAvg": 0.625,
"children": [
{
"name": "B1-C1-D1",
"scoreAvg": 0.7,
"children": [
{
"name": "B1-C1-D1-E1",
"value": 30,
"score": 0.8
},
{
"name": "B1-C1-D1-E2",
"value": 35,
"score": 0.6
}
]
},
{
"name": "B1-C1-D2",
"scoreAvg": 0.55,
"children": [
{
"name": "B1-C1-D2-E1",
"value": 31,
"score": 0.4
},
{
"name": "B1-C1-D2-E2",
"value": 23,
"score": 0.7
}
]
}
]
}
]
}
]
}
You can use a recursive function:
const obj = {
"name": "A1",
"children": [{
"name": "B1",
"children": [{
"name": "B1-C1",
"children": [{
"name": "B1-C1-D1",
"children": [{
"name": "B1-C1-D1-E1",
"value": 30,
"score": 0.8
},
{
"name": "B1-C1-D1-E2",
"value": 35,
"score": 0.5
}
]
},
{
"name": "B1-C1-D2",
"children": [{
"name": "B1-C1-D2-E1",
"value": 31,
"score": 0.4
},
{
"name": "B1-C1-D2-E2",
"value": 23,
"score": 0.7
}
]
}
]
}]
}]
}
function getWithAverageScore(objToRecurse) {
// If I have a score I am already done
if (objToRecurse.score) {
return objToRecurse;
}
// Otherwise, I get my children with their average score
const children = objToRecurse.children.map(getWithAverageScore);
return {
...objToRecurse,
children,
// And I set my scoreAvg to their average (score or scoreAvg)
scoreAvg: children.reduce((total, { score, scoreAvg }) => total + (score || scoreAvg), 0) / children.length
};
}
console.log(JSON.stringify(getWithAverageScore(obj), null, 2))
let o = {
"name": "A1",
"children": [
{
"name": "B1",
"children": [
{
"name": "B1-C1",
"children": [
{
"name": "B1-C1-D1",
"children": [
{
"name": "B1-C1-D1-E1",
"value": 30,
"score": 0.8
},
{
"name": "B1-C1-D1-E2",
"value": 35,
"score": 0.5
}
]
},
{
"name": "B1-C1-D2",
"children": [
{
"name": "B1-C1-D2-E1",
"value": 31,
"score": 0.4
},
{
"name": "B1-C1-D2-E2",
"value": 23,
"score": 0.7
}
]
}
]
}
]
}
]
};
function avgUp(object){
object.avgScore = 0;
if(object.children){
for(child of object.children){
object.avgScore += avgUp(child);
}
object.avgScore = object.avgScore /Math.max(1,object.children.length);
return object.avgScore;
}else{
return object.score;
}
}
avgUp(o);
console.log(JSON.stringify(o));

Map the name of nodes onto links

This is my data and I am trying to map the name of the nodes to the sources and targets of the links.
var x = {
"nodes": [
{
"name": "Decision 3a"
},
{
"name": "Req 1"
},
{
"name": "Req 3c"
},
{
"name": "Cloud Services"
}
],
"links": [
{
"source": "0",
"target": "3",
"value": 100
},
{
"source": "4",
"target": "2",
"value": 100
}
]
};
I want the object to look like this for my visualization--
var x = {
"nodes": [
{
"name": "Decision 3a"
},
{
"name": "Req 3"
},
{
"name": "Req 3c"
},
{
"name": "Req 3b"
}
],
"links": [
{
"source": "Decision 3a",
"target": "Req 3c",
"value": 100
},
{
"source": "Cloud Services",
"target": "Req 1",
"value": 100
}
]
};
I tried adding the id to the nodes and then map them but in that case the id remain there in the nodes object.
you need to loop through the each object in the links array and get the index from the nodes array and assign that value to the links array.
i hope the below code solves the issue
var x = {
"nodes": [
{
"name": "Decision 3a"
},
{
"name": "Req 1"
},
{
"name": "Req 3c"
},
{
"name": "Req 4"
},
{
"name": "Cloud Services"
}
],
"links": [
{
"source": "0",
"target": "3",
"value": 100
},
{
"source": "4",
"target": "2",
"value": 100
}
]
};
x.links.forEach(o => {
let name = x.nodes[parseInt(o.source)].name;
o["source"] = name;
})
console.log("output",x)

Categories

Resources