here my issue i unable to get the dynamic key pair value from the dynamic json
below is my json
var d = {
"pexels-photo.jpeg": {
"information": "laptop",
"desc": {
"mimetype": "image/jpeg",
"id": "shsj44",
"file_id": "pexels-photo.jpeg"
},
"_id": "shsj44"
}
}
here i tried below
Object.keys(d).forEach(function(key){
var value = d[key];
console.log(key + ':' + value) ;
});
i want to get the id value "_id" & "file_id" values
You can use Destructuring assignment
var d = {"dynamic": {"information": "laptop","desc": { "mimetype": "image/jpeg","id": "shsj44","file_id": "pexels-photo.jpeg" },"_id": "shsj44"}}
let dynamicKey = Object.keys(d)[0]
let {[dynamicKey]:{desc:{
file_id
},_id}} = d
console.log(file_id, '\n', _id)
That is because of the + before the value, which will try to concatenate the value and you will see [object object]
var d = {
"pexels-photo.jpeg": {
"information": "laptop",
"desc": {
"mimetype": "image/jpeg",
"id": "shsj44",
"file_id": "pexels-photo.jpeg"
},
"_id": "shsj44"
}
}
Object.keys(d).forEach(function(key) {
let value = d[key];
console.log(key + ' : ', value);
console.log(key + ' : ', value.desc.id);
});
You need to check whether the value is object or not, if yes then you need to loop over it again.
Following code will print every key-value pair in d
export class AppComponent implements OnInit {
d = {
'pexels-photo.jpeg': {
'information': 'laptop',
'desc': {
'mimetype': 'image/jpeg',
'id': 'shsj44',
'file_id': 'pexels-photo.jpeg'
},
'_id': 'shsj44'
}
};
ngOnInit(): void {
this.calc(this.d);
}
calc(val) {
Object.keys(val).forEach(key => {
const value = val[key];
if (typeof (value) === 'object') {
this.calc(value);
} else {
console.log(key + ':' + value);
}
});
}
}
Try this :
var d = {
"pexels-photo.jpeg": {
"information": "laptop",
"desc": {
"mimetype": "image/jpeg",
"id": "shsj44",
"file_id": "pexels-photo.jpeg"
},
"_id": "shsj44"
}
};
Object.keys(d).filter(key => {
Object.keys(d[key]).filter(item => {
if (item === 'desc') {
Object.keys(d[key][item]).filter(elem => {
if ((elem === 'id') || (elem === 'file_id')) {
console.log(elem + ' : ' + d[key][item][elem]);
}
});
}
})
});
I'm looking to create a valid nested Json file, from an array, with unique keys value. Currently, I'm only able to to display the json without any nested structure.
I would like to display to the console the following structure :
{
"Key" : "data1",
"header" : {
"title" : "data2",
"tag1" : "data3",
"tag2" : "data4"
},
"body" : {
"text" : "data5"
},
"updates" : {
"title" : "data6",
"text" : "data7"
},
"footer" : {
"title" : "data8",
"row1" :{
"col1" : {
"title" : "data9",
"text" : "data10"
},
"col2" : {
"title" : "data11",
"text" : "data12"
},
"col3" : {
"title" : "data13",
"text" : "data14"
}
},
"row2" :{
"col1" : {
"title" : "data15",
"text" : "data16"
},
"col2" : {
"title" : "data17",
"text" : "data18"
},
"col3" : {
"title" : "data19",
"text" : "data20"
}
},
"row3" :{
"col1" : {
"title" : "data22",
"text" : "data23"
},
"col2" : {
"title" : "data24",
"titlebis" : "data25",
"text" : "data26"
},
"col3" : {
"title" : "data27",
"text" : "data28"
}
},
"row4" :{
"col1" : {
"title" : "data29"
},
"website" : "data30",
"website-link" : "data31",
"email" : "data38",
"privacy" : "data32",
"privacy-link" : "data33",
"adr" : "data34",
"adr2" : "data35"
}
},
"other" : {
"short" : {
"des" : "data36"
},
"promovideo" : "data37"
}
}
here is what I already done:
var data = [["Key", "data1"],
["header.title", "data2"],
["header.tag1", "data3"],
["header.tag2", "data4"],
["body.text", "data5"],
["updates.title", "data6"],
["updates.text", "data7"],
["footer.title", "data8"],
["footer.row1.col1.title", "data9"],
["footer.row1.col1.text", "data10"],
["footer.row1.col2.title", "data11"],
["footer.row1.col2.text", "data12"],
["footer.row1.col3.title", "data13"],
["footer.row1.col3.text", "data14"],
["footer.row2.col1.title", "data15"],
["footer.row2.col1.text", "data16"],
["footer.row2.col2.title", "data17"],
["footer.row2.col2.text2", "data18"],
["footer.row2.col3.title", "data19"],
["footer.row2.col3.text", "data20"],
["footer.row3.col1.title", "data22"],
["footer.row3.col1.text", "data23"],
["footer.row3.col2.title", "data24"],
["footer.row3.col2.title", "data25"],
["footer.row3.col2.text", "data26"],
["footer.row3.col3.title", "data27"],
["footer.row3.col3.text", "data28"],
["footer.row4.col1.title", "data29"],
["footer.row4.website", "data30"],
["footer.row4.website-link", "data31"],
["footer.row4.email", "data31"],
["footer.row4.privacy", "data32"],
["footer.row4.privacy-link", "data33"],
["footer.row4.adr", "data34"],
["footer.row4.adr2", "data35"],
["other.short.des", "data36"],
["other.promovideo", "data37"],
];
// console.log(data);
data.sort(alphabetical); // Sort alphabetically our 2D array
CreateAndDisplayJson(data);
// Create a JSON file from Keys Trad Data
function CreateAndDisplayJson(GetKeysTraductionArrayData) {
var lenght = GetKeysTraductionArrayData.length;
var output = "{\n";
for (var i = 0; i < GetKeysTraductionArrayData.length; i++) {
var key = GetKeysTraductionArrayData[i][0];
var trad = GetKeysTraductionArrayData[i][1];
var nameSplit = key.split("."); // Check how many times we need to indent json from Key
if(nameSplit.length>1) { // The Key needs to be indented
var closeBraket = "";
var spacing = ""; // Json indentation
var saveSpacingTab = []; // Closing indentation
for (j=0; j <nameSplit.length; j++){ // We add the key + indentation
output += spacing+"\""+nameSplit[j]+"\" : { \n";
if (j==0 && i != GetKeysTraductionArrayData.length-1) {
closeBraket = spacing+"}, \n";
} else {
closeBraket = spacing+"} \n";
}
spacing +=" ";
saveSpacingTab[j] = closeBraket;
closingText = "";
if (j==nameSplit.length-1) { // last indentation of the Key
saveSpacingTab.reverse();
for ( k=0; k < saveSpacingTab.length ; k++) { // We create the Bracket indentation
closingText += saveSpacingTab[k];
}
output += spacing+"\""+nameSplit[j]+"\" : " + "\""+trad +"\"\n" + closingText; // last Row
}
}
} else {
output += "\""+key+"\" : " + "\""+trad +"\", \n";
}
}
// output += "}" + outputCommented;
output += "}";
console.log(output);
return output;
}
// Sort alphabetically our 2D array
function alphabetical(a, b) {
var A = a[0];
var B = b[0].toLowerCase();
A = A.toLowerCase();
B = B.toLowerCase();
if (A < B) return -1;
if (A > B) return 1;
return 0;
}
You can use forEach loop and inside split each key and then use reduce to build nested structure for each key.
var data = [["Key","data1"],["header.title","data2"],["header.tag1","data3"],["header.tag2","data4"],["body.text","data5"],["updates.title","data6"],["updates.text","data7"],["footer.title","data8"],["footer.row1.col1.title","data9"],["footer.row1.col1.text","data10"],["footer.row1.col2.title","data11"],["footer.row1.col2.text","data12"],["footer.row1.col3.title","data13"],["footer.row1.col3.text","data14"],["footer.row2.col1.title","data15"],["footer.row2.col1.text","data16"],["footer.row2.col2.title","data17"],["footer.row2.col2.text2","data18"],["footer.row2.col3.title","data19"],["footer.row2.col3.text","data20"],["footer.row3.col1.title","data22"],["footer.row3.col1.text","data23"],["footer.row3.col2.title","data24"],["footer.row3.col2.title","data25"],["footer.row3.col2.text","data26"],["footer.row3.col3.title","data27"],["footer.row3.col3.text","data28"],["footer.row4.col1.title","data29"],["footer.row4.website","data30"],["footer.row4.website-link","data31"],["footer.row4.email","data31"],["footer.row4.privacy","data32"],["footer.row4.privacy-link","data33"],["footer.row4.adr","data34"],["footer.row4.adr2","data35"],["other.short.des","data36"],["other.promovideo","data37"]]
let result = {}
data.forEach(([key, value]) => {
key.split('.').reduce((r, k, i, arr) => {
return r[k] || (r[k] = arr[i + 1] ? {} : value)
}, result)
})
console.log(result)
A non-ternary solution with reduce:
const data = [["Key","data1"],["header.title","data2"],["header.tag1","data3"],["header.tag2","data4"],["body.text","data5"],["updates.title","data6"],["updates.text","data7"],["footer.title","data8"],["footer.row1.col1.title","data9"],["footer.row1.col1.text","data10"],["footer.row1.col2.title","data11"],["footer.row1.col2.text","data12"],["footer.row1.col3.title","data13"],["footer.row1.col3.text","data14"],["footer.row2.col1.title","data15"],["footer.row2.col1.text","data16"],["footer.row2.col2.title","data17"],["footer.row2.col2.text2","data18"],["footer.row2.col3.title","data19"],["footer.row2.col3.text","data20"],["footer.row3.col1.title","data22"],["footer.row3.col1.text","data23"],["footer.row3.col2.title","data24"],["footer.row3.col2.title","data25"],["footer.row3.col2.text","data26"],["footer.row3.col3.title","data27"],["footer.row3.col3.text","data28"],["footer.row4.col1.title","data29"],["footer.row4.website","data30"],["footer.row4.website-link","data31"],["footer.row4.email","data31"],["footer.row4.privacy","data32"],["footer.row4.privacy-link","data33"],["footer.row4.adr","data34"],["footer.row4.adr2","data35"],["other.short.des","data36"],["other.promovideo","data37"]]
const result = data.reduce((all, [keys, val]) => {
keys.split('.').reduce((obj, key, i, arr) => {
if (i === arr.length - 1) {
obj[key] = val;
} else {
if (!obj.hasOwnProperty(key)) {
obj[key] = {};
};
}
return obj[key];
}, all);
return all;
}, {});
console.log(result);
I have the following JSON object. I need to convert it in javascript into a one-level associative array. (key-value pairs) I've written a recursive function but can't seem to get it to work the way I want it to. Kindly refer to the example below for what I've written:
{
"Title" : "Test Match",
"Players" : [
{
"ID" : 1,
"Name" : "Ma Couella",
"Results" : [2,2,0],
"TeamMates" : [
{
"ID" : 2,
"Age" : 24,
"LikesToWin" : false
}
]
}, {
"ID" : 22,
"Name" : "Shawn Kato",
"Results" : [2,1,0],
"TeamMates" : [
{
"Name" : "Gerald Anderson",
"Age" : 24,
"LikesToWin" : false
}
]
}
],
"Referees" : [
{
"ID" : 10,
"Name" : "Janice Tieu",
"YearsAsReferee" : 10,
"EmploymentHistory" : [
{
"JobTitle" : "Senior Referee",
"YearsOnTheJob" : 20,
"FavouriteMatchesRefereeed" : [
{
"Title" : "Duran vs Leonard 1",
"Year" : 1992,
"Description" : "I was refereeing the test match but I put on make up so Duran lost the bout."
}, {
"Title" : "Duran vs Leonard 2",
"Year" : 1994,
"Description" : "I was refereeing the second match but I put on make up so Duran lost another bout."
}
]
}, {
"JobTitle" : "Juniour Refereee",
"YearsOnTheJob" : 3,
"FavouriteMatchesRefereeed" : [
{
"Title" : "Mexican Figher Jones vs Anna Himley",
"Year" : 1972,
"Description" : "I coached this match. Hehe."
}, {
"Title" : "Jennifer from the block 2",
"Year" : 1982,
"Description" : "I coached this other match. Hehe."
}
]
}
]
}
]
}
Example of expected associative array below:
[
"Title" => "Test Match",
"Players[0][ID]" => 0,
// rest of the array...
"Players[0][Teammates][0][ID]" => 2,
// rest of the array...
"Referees[0][EmploymentHistory][FavouriteMatchesRefereeed][Title]" => "Duran vs Leonard 1"
]
Here is what I've done so far (javascript)
function converJSONToStrings(values, prevParent){
console.log(values);
var result = [];
for (var key in values)
{
var value = values[key];
if(value.constructor === Array) {
// console.log("Found object array in key", key );
for(var x = 0; x<value.length; x++){
result[key + '[' + x + ']'] = converJSONToStrings(value[x]);
}
} else if (typeof value == 'object') {
for(var x in value){
result[key + '[' + x + ']'] = converJSONToStrings(value[x]);
}
} else {
result[key] = value;
}
}
return result;
}
Finally came up with a solution! Code below...
/**
* Formats the JSON result to an associative array, concatenating child and parent keys
*/
var convertJSONAssoc = function(obj, firstlevel) {
// consider string, number and boolean values in JSON as the last
// elements and can't be recursed into any further
if (typeof obj == 'string' || typeof obj == 'number' || typeof obj == 'boolean') {
var ab = [];
var bc = {};
bc.key = '';
bc.val = obj;
ab.push(bc);
return ab;
}
// the top most call which builds the final result
if (firstlevel) {
var result = {};
for (key in obj) {
var val = obj[key];
var s = convertJSONAssoc(val, false);
for (var o = 0; o < s.length; o++) {
var v = s[o];
result[key + v['key']] = v['val'];
}
}
return result;
} else {
// this is where the recursion happens. As long as objects are found,
// we use the code below to keep on parsing obj keys
var paths = [];
for (var key in obj) {
var val = obj[key];
var s = convertJSONAssoc(val, false);
for (var o = 0; o < s.length; o++) {
var v = s[o];
var de = {};
de.key = "[" + key + "]" + v['key'];
de.val = v['val'];
paths.push(de);
}
}
return paths;
}
}
This is an old question that came back up because of edits from the OP. Modern techniques make this a bit easier than it was when the question was written.
This uses two functions. pathEntries I use to turn objects into a similar format that I find more useful, something like
[
[['Title'], 'Test Match'],
[['Players', 0, 'ID'], 1],
[['Players', 0, 'Name'], 'Ma Couella,
// ...
[['Referees', 0, 'EmploymentHistory', 1, 'FavouriteMatchesRefereeed', 1, 'Year'], 1982],
[['Referees', 0, 'EmploymentHistory', 1, 'FavouriteMatchesRefereeed', 1, 'Description'], 'I coached this other match. Hehe.']
]
Then convert, with a combination of key mapping and Object.fromEntries (which is easy to shim if you need to support environments without it), turns this into your required format. It looks like this:
const pathEntries = (obj) =>
Object (obj) === obj
? Object .entries (obj) .flatMap (
([k, x]) => pathEntries (x) .map (([p, v]) => [[k, ... p], v])
)
: [[[], obj]]
const convert = (obj) =>
Object .fromEntries (
pathEntries (obj) .map (([k, v]) => [
k[0] + k .slice (1) .map (n => `[${n}]`) .join (''),
v
])
)
const data = {Title: "Test Match", Players: [{ID: 1, Name: "Ma Couella", Results: [2, 2, 0], TeamMates: [{ID: 2, Age: 24, LikesToWin: !1}]}, {ID: 22, Name: "Shawn Kato", Results: [2, 1, 0], TeamMates: [{Name: "Gerald Anderson", Age: 24, LikesToWin: !1}]}], Referees: [{ID: 10, Name: "Janice Tieu", YearsAsReferee: 10, EmploymentHistory: [{JobTitle: "Senior Referee", YearsOnTheJob: 20, FavouriteMatchesRefereeed: [{Title: "Duran vs Leonard 1", Year: 1992, Description: "I was refereeing the test match but I put on make up so Duran lost the bout."}, {Title: "Duran vs Leonard 2", Year: 1994, Description: "I was refereeing the second match but I put on make up so Duran lost another bout."}]}, {JobTitle: "Juniour Refereee", YearsOnTheJob: 3, FavouriteMatchesRefereeed: [{Title: "Mexican Figher Jones vs Anna Himley", Year: 1972, Description: "I coached this match. Hehe."}, {Title: "Jennifer from the block 2", Year: 1982, Description: "I coached this other match. Hehe."}]}]}]}
console .log (convert (data))
.as-console-wrapper {max-height: 100% !important; top: 0}
Note that I often write pathEntries in terms of simpler getPaths and path functions. That is cleaner but less efficient as it requires extra traversals of the object.