Multiple header rows exporting Google Sheets to JSON - json

I am trying to export google sheet to JSON formatted text so I can read it into another program. Entries are indexed by multiple headers for the row and columns. I can't share the data as it is not compliant with GDPR, so I have an example below.
E.g.
If I was constructing a table of spells in D&D to determine when they were introduced, I would have the field being School of Magic, the Subfield being the spell down the left column, and then across the header would be indexed by the edition (1 through 5), with sub headed with Base and then name of expansion, each cell is empty or just has a string saying "Yes" if it is present.
Image added to clarify.
Example table structure
This would then return an entry like this when exported
{
"School of Magic":"Necromancy",
"Spell":"Abi-Dalzim's Horrid Wilting",
"Edition":"5th",
"Book":"Elemental Evil Player's Companion"
"Elemental Evil Player's Companion": "Yes"
}
I am using this as a base to export
https://gist.githubusercontent.com/pamelafox/1878143/raw/6c23f71231ce1fa09be2d515f317ffe70e4b19aa/exportjson.js?utm_source=thenewstack&utm_medium=website&utm_campaign=platform
But I am incredibly new to JSON and I can't quite work out how to have multiple headers.
Any help here would be appreciated regarding how to adapt this or even just where to look to solve this sort of problem as I can't find documentation that points me in this direction.
Below is a link to a csv file of a similar table, hopefully I haven't just doxxed myself.
https://docs.google.com/spreadsheets/d/e/2PACX-1vSEHGJgn3x4gpyXfBYqRSoJieiZIoDSbJt_pys_TQM-SzXVJjubJbzOvmUT0cUSRRBYUpkKxPq1IOj_/pub?output=csv
The idea would be that in this example the output would show whenever a given spell was introduced within each edition. So the output would be like:
{
"School of Magic":"Necromancy",
"Spell":"Abi-Dalzim's Horrid Wilting",
"Edition":4,
"Book":"Exp2",
"Exp2": "Yes"
"Edition":5,
"Book":"Elemental Evil Player's Companion",
"Elemental Evil Player's Companion": "Yes"
}
{
"School of Magic":"Necromancy",
"Spell":"Raise Undead",
"Edition":1,
"Book":"Base",
"Base": "Yes",
"Edition":2,
"Book":"Base",
"Base": "Yes",
"Edition":3,
"Book":"Base",
"Base": "Yes",
"Edition":4,
"Book":"Base",
"Base": "Yes",
"Edition":5,
"Book":"Base",
"Base": "Yes"
}
If this makes sense? In the true data these cells contain information of interactions between the subcolumns so it is important that I can identify which sub columns and what the entry is.

Try
function table2json() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var [headers, ...rows] = sheet.getDataRange().getValues();
var items = []
rows.forEach(function(r) {
var obj={}
r.forEach(function (c, j) {
obj[headers[j]] = c
})
items.push(obj)
})
console.log(JSON.stringify(items))
}
edit
according to your new data and your spreadsheet, try
function myFunction() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var data = sh.getDataRange().getValues()
// rebuild a complete set
var temp = ''
data.forEach((r, i) => {
if (i < 2) {
r.forEach((c, j) => {
if (j > 1) {
if (c == '') { data[i][j] = temp } else { temp = data[i][j] }
}
})
}
else {
if (r[0] == '') { data[i][0] = temp } else { temp = data[i][0] }
}
})
// extract informations
data.forEach((r, i) => {
if (i > 2) {
var result = []
if (r[0] == '') { data[i][0] = temp } else { temp = data[i][0] }
result.push([data[2][0], data[i][0]])
result.push([data[2][1], data[i][1]])
r.forEach((c, j) => {
if (j > 2) {
if (c != '') {
result.push([data[0][j], data[1][j]])
result.push(['Book', data[2][j]])
result.push([data[2][j], data[i][j]])
}
}
})
console.log((result))
}
})
}
result
[ [ 'School', 'Necromancy' ],
[ 'Spell', 'Abi-Dalzim\'s...' ],
[ 'Edition', 4 ],
[ 'Book', 'Exp2' ],
[ 'Exp2', 'Yes' ],
[ 'Edition', 5 ],
[ 'Book', 'Elemental Evil ...' ],
[ 'Elemental Evil ...', 'Yes' ] ]
[ [ 'School', 'Necromancy' ],
[ 'Spell', 'Raise Dead' ],
[ 'Edition', 2 ],
[ 'Book', 'Base' ],
[ 'Base', 'Yes' ],
[ 'Edition', 3 ],
[ 'Book', 'Base' ],
[ 'Base', 'Yes' ],
[ 'Edition', 4 ],
[ 'Book', 'Base' ],
[ 'Base', 'Yes' ],
[ 'Edition', 5 ],
[ 'Book', 'Base' ],
[ 'Base', 'Yes' ] ]

Related

how to filter json data with multiple conditions in flutter?

Hi all I want to add one more condition to filter json list more effectively in flutter.
And my json looks like this
{
"product": "butox 50 ml",
"agencies": [
{
"agency": "Sai Ganesh",
"agency uid": "8"
},
{
"agency": "slv",
"agency uid": "10"
}
]
},
{
"product": "voveran sr 100",
"agencies": [
{
"agency": "Sree Enterprises",
"agency uid": "31"
}
]
}
below is my code I want to filter product name and from one particular agency based on uid
List<mmamodel> results = [];
if (productName.isEmpty) {
results = mmaData;
} else {
results = mmaData
.where((element) => element.product
.toString()
.toLowerCase()
.contains(productName.toLowerCase())
&&
element.agencies!
.where((agency) => agency.agencyUid
.toString()
.toLowerCase()
.contains(Uid.toLowerCase()))
.toList().)
.toList();
}
foundProduct.value = results;
results = mmaData
.where((element) =>
element.product
.toString()
.toLowerCase()
.startsWith(playerName.toLowerCase()) &&
element.agencies!.any((agency) => agency.agencyUid == Uid))
.toList();

Google Sheet: How to define the "cols.label" value in JSON export?

I use a google sheet as an endpoint to import data into an html table. Depending on the type of data in the sheet I get a different JSON structure.
To explain the problem, I built a Google sheet with two very simple tables.
The only difference between the two tables is the Age field which is numeric in Sheet1 and textual in Sheet2.
Link document
If I use sheets as JSON endpont I get this behavior: Sheet1 exports the header correctly, but Sheet2 shows an empty header (column headers become normal row values).
Sheet1 JSON
{
"version": "0.6",
"reqId": "0",
"status": "ok",
"sig": "325167901",
"table": {
"cols": [
{
"id": "A",
"label": "Name",
"type": "string"
},
{
"id": "B",
"label": "Age",
"type": "number",
"pattern": "General"
}
],
"rows": [
{
"c": [
{
"v": "Vittorio"
},
{
"v": 52.0,
"f": "52"
}
]
}
],
"parsedNumHeaders": 1
}
}
Sheet2 JSON
{
"version": "0.6",
"reqId": "0",
"status": "ok",
"sig": "1566616543",
"table": {
"cols": [
{
"id": "A",
"label": "",
"type": "string"
},
{
"id": "B",
"label": "",
"type": "string"
}
],
"rows": [
{
"c": [
{
"v": "Name"
},
{
"v": "Age"
}
]
},
{
"c": [
{
"v": "Vittorio"
},
{
"v": "52"
}
]
}
],
"parsedNumHeaders": 0
}
}
Is there any way to fix Sheet2 behavior?
It seems there is a problem, meanwhile what I suggest is to test the JSON endpont labels as follows
const jsonString = `/*O_o*/
google.visualization.Query.setResponse({"version":"0.6","reqId":"0","status":"ok","sig":"1566616543","table":{"cols":[{"id":"A","label":"","type":"string"},{"id":"B","label":"","type":"string"}],"rows":[{"c":[{"v":"Name"},{"v":"Age"}]},{"c":[{"v":"Vittorio"},{"v":"52"}]}],"parsedNumHeaders":0}});`
function jsonWithLabels(jsonString) {
var json = JSON.parse(jsonString.slice(47,-2))
var labels = json.table.cols.map(c => c.label)
return (labels.join('') != '')
}
function test(){
console.log (jsonWithLabels(jsonString))
}
if false, you need to fetch the labels from row 1
const jsonString = `/*O_o*/
google.visualization.Query.setResponse({"version":"0.6","reqId":"0","status":"ok","sig":"1566616543","table":{"cols":[{"id":"A","label":"","type":"string"},{"id":"B","label":"","type":"string"}],"rows":[{"c":[{"v":"Name"},{"v":"Age"}]},{"c":[{"v":"Vittorio"},{"v":"52"}]}],"parsedNumHeaders":0}});`
var json = JSON.parse(jsonString.slice(47,-2))
var labels = json.table.cols.map(c => c.label)
console.log (labels.join('') != '')
here is a complete script to rebuild the table with and without labels
const jsonString = `/*O_o*/
google.visualization.Query.setResponse({"version":"0.6","reqId":"0","status":"ok","sig":"1566616543","table":{"cols":[{"id":"A","label":"","type":"string"},{"id":"B","label":"","type":"string"}],"rows":[{"c":[{"v":"Name"},{"v":"Age"}]},{"c":[{"v":"Vittorio"},{"v":"52"}]}],"parsedNumHeaders":0}});`
document.getElementById("json").innerHTML = myItems(jsonString.slice(47, -2))
function myItems(jsonString) {
var json = JSON.parse(jsonString);
var table = '<table>';
var flag = jsonWithLabels(json);
if (flag) {
table += '<tr>';
json.table.cols.forEach(colonne => table += '<th>' + colonne.label + '</th>')
table += '</tr>';
}
json.table.rows.forEach((row, index) => {
table += '<tr>';
row.c.forEach(cel => {
try { var valeur = cel.f ? cel.f : cel.v }
catch (e) { var valeur = '' }
if (!flag && index == 0) { table += '<th>' + valeur + '</th>' }
else { table += '<td>' + valeur + '</td>' }
})
table += '</tr>';
})
table += '</table>';
return table
}
function jsonWithLabels(json) {
var labels = json.table.cols.map(c => c.label);
return (labels.join('') != '')
}
table {border-collapse: collapse;}
th,td {border: 1px solid black;}
<div id="json">json here</div>

ES6 filter an array of objects retrieving a field that is an empty array or does not contain certain value

I am trying to filter the following array
const matches = [
{
"match": "1",
"teams": [
[
{ "name": "david"},
{ "name": "tom"}
],
[
{ "name": "liam"},
{ "name": "noah"}
]
]
},
{
"match": "2",
"teams": [
[
{ "name": "david"},
{ "name": "tom"}
],
[
{ "name": "oliver"},
{ "name": "elijah"}
]
]
},
{
"match": "3",
"teams": []
}
]
I want to retrieve the objects where the teams array is empty, or "oliver" does not belong to the teams. It should retrieve match "1" and "3"
I tried the following
matches.filter(match => match.teams.length === 0 || !match.teams.includes({ name: "oliver" })
matches.filter(match => match.teams.length === 0 || !match.teams.some(team => team.name === "oliver" })
but I am getting the 3 objects
match.teams is an array of arrays of players
try this
matches.filter(match =>
match.teams.length === 0 ||
match.teams.every(team =>
team.every(player => player.name !== "oliver" )
)
)
// use array.flat method. teams is arrays of arrays
const result=matches.filter(match=>{
if(!match.teams.length){
return true;
}
const teamArray=match.teams.flat(1);
console.log(teamArray);
const search=teamArray.find(player=>player.name!=="oliver");
if(search){
return true;
}
return false;
});

How to remove objoct from object by finding in type script

This is my object
"filterValue":[
{"label":"--Select a Member--","value":""},
{"label":"ghi.jkl","value":{"Id":"1",}},
{"label":"abc.def","value":{"Id":"2",}},
{"label":"asd.vdf","value":{"Id":"3",}},
]
from this i want to search where value.Id = 2 and i want to remove that obeject line.
how can i do that..?
note:first value will be empty there is no data in value.
i have tried something like this:
filterValue.splice( filterValue.indexOf(2), 1 );
You can't use indexOf in this case because you are checking a complex object but you can use findIndex like this:
filterValue.splice( filterValue.findIndex(a => a.Id == 2), 1 );
You might want to change the code the check if findIndex actually found something by checking if it returns something larger than (or equal to) 0.
You can use filter to get a new filtered array (filteredArr):
var arr = [
{"label":"--Select a Member--","value":""},
{"label":"ghi.jkl","value":{"Id":"1",}},
{"label":"abc.def","value":{"Id":"2",}},
{"label":"asd.vdf","value":{"Id":"3",}}
];
var filteredArr = arr.filter((x) => JSON.stringify(x.value) !== JSON.stringify({"Id":"2"}));
console.log(filteredArr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You have a couple of subtly traps to avoid with your specific example.
The structure of items differs, so you need to be careful that you don't have a problem with the "--Select a Member--" item, which doesn't have a value.Id.
The example below cheaply solves the type issue (the best common type between the array members doesn't contain the property you are interested in).
const items = [
{ "label": "--Select a Member--", "value": "" },
{ "label": "ghi.jkl", "value": { "Id": "1", } },
{ "label": "abc.def", "value": { "Id": "2", } },
{ "label": "asd.vdf", "value": { "Id": "3", } },
];
const filtered = items.filter((i: any) => !i.value || !i.value.Id || i.value.Id !== '2');
console.log(filtered);
Output:
[
{"label":"--Select a Member--","value":""},
{"label":"ghi.jkl","value":{"Id":"1"}},
{"label":"asd.vdf","value":{"Id":"3"}}
]
const obj = {
filterValue: [
{ label: "--Select a Member--", value: "" },
{ label: "ghi.jkl", value: { Id: "1" } },
{ label: "abc.def", value: { Id: "2" } },
{ label: "asd.vdf", value: { Id: "3" } }
]
};
var changedObj = obj.filterValue.filter((data, index) => {
return data.value.Id != "1";
});
console.log(changedObj);

Access child token in JSON

In the below JSON I was trying to access the second array in the header.Basically "Node", "Percentage", "Time","File System" needs to captured as I will have to insert into SQL.My code is giving the complete array of header.
JObject jsonObject = JObject.Parse(jsonString);
List<string> childTokens = new List<string>();
foreach (var childToken in jsonObject.Children<JProperty>())
childTokens.Add(childToken.Name);
foreach (string childToken in childTokens)
{
if (jsonObject[childToken] is JObject)
{
JObject jObject = (JObject)jsonObject[childToken];
var jProperty = jObject.Children<JProperty>();
try
{
if (jProperty.LastOrDefault(x => x.Name == "header") != null)
{
foreach (var headerValue in jProperty.LastOrDefault(x => x.Name == "header").Value.Children())
table.Columns.Add("[" + headerValue.ToString() + "]");
table.Columns.Add("[ID]");
table.Columns.Add("[comments]");
}
JSON sample:
"DISK" : {
"alarm_count" : 5,
"column_width" : [
12,
14,
16,
14
],
"header" : [
[
"",
"Max Disk Usage",
3
],
[
"Node",
"Percentage",
"Time",
"File System"
]
] }
I can have number of arrays in header .. don't want to hardcode it.. I should be always be able to pick the last array in header child token..Please advise .. thanks
Assuming your json snippet was valid and is part of an object like:
{
"DISK": {
"alarm_count": 5,
"column_width": [
12,
14,
16,
14
],
"header": [
[
"",
"Max Disk Usage",
3
],
[
"Node",
"Percentage",
"Time",
"File System"
]
]
}
}
You could do this:
JObject obj = ...;
var secondHeader = obj["DISK"]["header"].Last();