Actual Output :
{
"workbookInformation": {
...
},
"dashboard1": {
"auto-hidden": "0",
"maximized": "1",
"worksheet": {
"worksheet8": "APAC",
"worksheet2": "Freq_SC_Value",
"worksheet3": "L1 Type Filter",
"worksheet1": "Pillar Name"
},
"class": "dashboard",
"name": "AnalysisByGeography"
},
"dashboard2": {
...
},
"datasources3": {
...
}
}
Required Output :
{
"workbookInformation": {
...
},
"AnalysisByGeography": {
"auto-hidden": "0",
"maximized": "1",
"worksheet": {
"APAC": "worksheet8",
"Freq_SC_Value": "worksheet2",
"L1 Type Filter": "worksheet3",
"Pillar Name": "worksheet1"
},
"class": "dashboard",
"name": "AnalysisByGeography"
},
"dashboard2": {
...
},
"datasources3": {
...
}
}
I tried with code which gives key name . i tried "//jashkenas.github.io/underscore/underscore-min.js" for swapping the keys. I tried external JS file for reversing the key value pair.
Try to use JSON.stringify(youredata). Otherwise maybe u need to split the given data and convert the array with the same function to a json-type.
Okay, here I wrote for you how to do it, because I don't see more how to explain it. But I strongly suggest, that if you begin in JavaScript, to learn more before asking those type of questions.
Maybe other validations may be needed. Also, I did it only for keys starting with "dashboard", even though I thought it would probably be for all keys having a string plus a number after then and containing an object that has a key "name" in it. If you want to learn, you shall fix that by yourself as you have a pretty strong base here.
Hoping you'll have find learning as I had and still have!
var data =
{
"workbookInformation": {
"a": "..."
},
"dashboard1": {
"auto-hidden": "0",
"maximized": "1",
"worksheet": {
"worksheet8": "APAC",
"worksheet2": "Freq_SC_Value",
"worksheet3": "L1 Type Filter",
"worksheet1": "Pillar Name"
},
"class": "dashboard",
"name": "AnalysisByGeography"
},
"dashboard2": {
"a": "..."
},
"datasources3": {
"a": "..."
}
}
var isDashboard = new RegExp('dashboard[0-9]+', 'i');
var isWorksheet = new RegExp('worksheet[0-9]+', 'i');
for(var dataKey in data) {
var innerData = data[dataKey];
if (typeof(innerData["worksheet"]) == "object") {
var newWS = {};
for(var wsKey in innerData["worksheet"]) {
newWS[innerData["worksheet"][wsKey]] = wsKey;
}
innerData["worksheet"] = newWS;
}
if (isDashboard.test(dataKey) && innerData['name']) {
delete data[dataKey];
dataKey = innerData['name'];
}
data[dataKey] = innerData;
}
console.log(data);
Related
I am obtaining a JSON from another application. I would like to parse that JSON and read the data present in them. The JSON contains some of the user-defined data which are dynamic and the key/value pair can be dynamic so I am a bit confused about how to read these dynamic data and do further processing.
Following is the sample JSON that I would like to process:
{
"context": [
{
"one": "https://example.one.com"
},
{
"two": "https://example.two.com"
},
{
"three": "https://example.three.com"
}
],
"name": "Batman",
"age": "30",
"one:myField": {
"two:myField2": "Hello"
},
"three:myField3": "Hello2"
}
I am able to read some of the static/well-defined data directly such as name & age but I am not understanding how to read some of the user-defined/dynamic data from this JSON as it does not have a definite key/value or there is no guarantee that it will appear in the order after the age property.
I am trying to find a way to read/obtain all the user-defined data from this JSON:
"one:myField": {
"two:myField2": "Hello"
},
"three:myField3": "Hello2"
Is there a direct way to achieve this or use some library? I am developing the application using Vuejs/Nuxtjs.
I think that's not the best api you are using, you should have constant object parameters that you always know how to find things. If you want to find not known parameters you can parse JSON to object and loop throug it.
const object = { a: 1, b: 2, c: 3 };
for (const property in object) {
console.log(`${property}: ${object[property]}`);
}
You can simply achieve that by iterating over Object.keys().
Demo :
const jsonData = {
"context": [
{
"one": "https://example.one.com"
},
{
"two": "https://example.two.com"
},
{
"three": "https://example.three.com"
}
],
"name": "Batman",
"age": "30",
"one:myField": {
"two:myField2": "Hello"
},
"three:myField3": "Hello2"
};
Object.keys(jsonData).forEach(key => {
if (typeof jsonData[key] === 'object') {
Object.keys(jsonData[key]).forEach(innerObjKey => {
console.log(innerObjKey, jsonData[key][innerObjKey])
})
} else {
console.log(key, jsonData[key])
}
})
Combining Object.keys with a recursive function, even if you have multiple nested objects, it will work without having to refactor your code everytime!
const jsonData = {
context: [
{
one: "https://example.one.com",
},
{
two: "https://example.two.com",
},
{
three: "https://example.three.com",
},
],
name: "Batman",
age: "30",
"one:myField": {
"two:myField2": "Hello",
"one_nested:myField": {
another_nested_key: "another_nested_value",
},
},
"three:myField3": "Hello2",
};
recursive(jsonData);
function recursive(nestedKey) {
if (typeof nestedKey !== "object") return;
Object.keys(nestedKey).forEach((key) => {
if (typeof nestedKey[key] === "object") {
recursive(nestedKey[key]);
} else {
console.log(key, nestedKey[key]);
// add your conditions here
if (key === "name") {
// bla bla bla
}
}
});
}
In Javascript, how to retrieve an object in an array by one of its property ?
Hi all,
let's assume that we have the below :
"Attributes":[
{
"Name":"Brief",
"Value":"This skirt was fabriced from ...."
},
{
"Name":"Details",
"Value":"Measurements and Pictures are real"
},
{
"Name":"SKUNumber",
"Value":"12345678"
}
]
What I need to do is to get the value of "Value" based on "Name"..
For example :
console.log(Attributes.Brief) ==> "This skirt was fabriced from ...."
So I need a function to help doing that
Note that I don't want to use the index of the object, because its order may changed.
Thank you
Well, it's always better to show what you have attempted rather than just asking..
You can use Array.find to achieve this
let Attributes = [
{
"Name":"Brief",
"Value":"This skirt was fabriced from ...."
},
{
"Name":"Details",
"Value":"Measurements and Pictures are real"
},
{
"Name":"SKUNumber",
"Value":"12345678"
}
]
function getValueByName(name) {
return Attributes.find(d => d.Name.toLowerCase() == name.toLowerCase()).Value
}
console.log(getValueByName('Brief'))
console.log(getValueByName('details'))
console.log(getValueByName('SKUNumber'))
One option you have is to use Array.prototype.filter:
const d = [{
"Name": "Brief",
"Value": "This skirt was fabriced from ...."
},
{
"Name": "Details",
"Value": "Measurements and Pictures are real"
},
{
"Name": "SKUNumber",
"Value": "12345678"
}
]
console.log(d.filter(x=>x.Name==="Brief")[0].Value)
You can also make it more generic:
const d = [{
"Name": "Brief",
"Value": "This skirt was fabriced from ...."
},
{
"Name": "Details",
"Value": "Measurements and Pictures are real"
},
{
"Name": "SKUNumber",
"Value": "12345678"
}
]
const getValOfXfromArrByValOfY = (arr, x, y, val) => arr.find(z => z[y] === val)[x]
console.log(getValOfXfromArrByValOfY(d, 'Value', 'Name', 'SKUNumber'))
You could use a Proxy with a getter for the key, which returns a find of the object with the value.
var object = { attributes: [{ Name: "Brief", Value: "This skirt was fabriced from ...." }, { Name: "Details", Value: "Measurements and Pictures are real" }, { Name: "SKUNumber", Value: "12345678" }] },
attributes = new Proxy(
object.attributes,
{ get: (array, prop) => (array.find(({ Name }) => Name === prop) || {}).Value }
);
console.log(attributes.Brief);
console.log(attributes.SKUNumber);
You can use javascript find function see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find see bellow sample code:
var Attributes =[
{
"Name":"Brief",
"Value":"This skirt was fabriced from ...."
},
{
"Name":"Details",
"Value":"Measurements and Pictures are real"
},
{
"Name":"SKUNumber",
"Value":"12345678"
}
]
var found = Attributes.find(function(element) {
return element.Name == "Details";
});
console.log(found.Value); //output : Measurements and Pictures are real
I use ajv to validate JSON data model before inserting/updating my database.
Today I want to use this structure:
const dataStructure = {
xxx1234: { mobile: "ios" },
yyy89B: { mobile: "android" }
};
My keys are dynamic because they are ids.
Do you know how to validate it with ajv ?
PS: as an alternative solution, i can of course use this structure:
const dataStructure = {
mobiles: [{
id: xxx1234,
mobile: "ios"
}, {
id: yyy89B,
mobile: "android"
}]
};
Then I would have to loop on the array to find the ids I want.
All my queries will become more complex, it bothers me.
Thank you for your help !
Below example may help you.
1.Validate dynamic key value
Update regex with your requirement.
const dataStructure = {
11: { mobile: "android" },
86: { mobile: "android" }
};
var schema2 = {
"type": "object",
"patternProperties": {
"^[0-9]{2,6}$": { //allow key only `integer` and length between 2 to 6
"type": "object"
}
},
"additionalProperties": false
};
var validate = ajv.compile(schema2);
console.log(validate(dataStructure)); // true
console.log(dataStructure);
2.Validate array of JSON with simple data types.
var schema = {
"properties": {
"mobiles": {
"type": "array", "items": {
"type": "object", "properties": {
"id": { "type": "string" },
"mobile": { "type": "string" }
}
}
}
}
};
const data = {
mobiles: [{
id: 'xxx1234',
mobile: "ios"
}]
};
var validate = ajv.compile(schema);
console.log(validate(data)); // true
console.log(data);
You can add your validation as per requirement.
I am using the following code to call an API and return results:
api.jobs.all(function(response) {
const obj = response.data.map(function(item) {
return [item.id, item.billed.amountString];
});
});
With the following JSON:
{
"data": [
{
"id": 2090170,
"deadline": null,
"jobId": {
"id": 1644
},
"billed": {
"amountString": 200,
"currencyType": "CAD"
}
},
{
"id": 2090171,
"deadline": null,
"jobId": {
"id": 1645
},
"billed": {
"amountString": 400,
"currencyType": "USD"
}
}]}
The code is working fine, for the most part I am getting back good results, with the exception of: billed.amountString
I keep getting the following error:
TypeError: Cannot read property 'amountString' of null
Can anyone see why this would be returning null?
Also, is there a way in which I could loop through the API call and force it to do the following:
If .amountString === null, .amountString = "";
var response = {
"data": [
{
"id": 2090170,
"deadline": null,
"jobId": {
"id": 1644
},
"billed": {
"amountString": 200,
"currencyType": "CAD"
}
},
{
"id": 2090171,
"deadline": null,
"jobId": {
"id": 1645
},
"billed": {
"amountString": 400,
"currencyType": "USD"
}
}]};
const obj = (response.data).map(function(item) {
return [item.id, item.billed.amountString];
});
console.log(obj);
You could use the library lodash. The lodash method get can be used to try and access an object field. If it does not exist you can specify a default return value. See https://lodash.com/ .
// This will try to access item.billed.amountString
// If an item does not exist anywhere along the way
// it will return the default.
// _.get( OBJECT, PATH, DEFAULT )
_.get(item, ['billed', 'amountString'], '')
I have a nested array like this:
array = [
{
"id": "67",
"sub": [
{
"id": "663",
},
{
"id": "435",
}
]
},
{
"id": "546",
"sub": [
{
"id": "23",
"sub": [
{
"id": "4",
}
]
},
{
"id": "71"
}
]
}
]
I need to find 1 nested object by its id and get all its parents, producing an array of ids.
find.array("71")
=> ["546", "71"]
find.array("4")
=> ["546", "23", "4"]
What's the cleanest way to do this? Thanks.
Recursively:
function find(array, id) {
if (typeof array != 'undefined') {
for (var i = 0; i < array.length; i++) {
if (array[i].id == id) return [id];
var a = find(array[i].sub, id);
if (a != null) {
a.unshift(array[i].id);
return a;
}
}
}
return null;
}
Usage:
var result = find(array, 4);
Demo: http://jsfiddle.net/Guffa/VBJqf/
Perhaps this - jsonselect.org.
EDIT: I've just had a play with JSONSelect and I don't think it's appropriate for your needs, as JSON does not have an intrinsic 'parent' property like xml.
It can find the object with the matching id, but you can't navigate upwards from that. E.g.
JSONSelect.match(':has(:root > .id:val("4"))', array)
returns me:
[Object { id="4"}]
which is good, it's just that I can't go anywhere from there!