I am working with Google Apps Script and I can retrieve the Google Spreadsheet Data as 2D array. I want to convert this array into a tree representation to build a folder hierarchy in Google Drive.
Here is the 2D Array which I can get from Google Spreadsheet.
var data = [
["F1", "F1S1","",""],
["", "F1S2", "F1S2S1", ""],
["", "", "F1S2S2", ""],
["", "F1S3", "", ""],
["F2", "F2S1", "", ""],
["", "F2S2", "F2S2S1", ""],
["", "", "F2S2S2", "F2S2S2S1"],
["", "", "", "F2S2S2S2"]
]
Now I am trying to turn it as below JSON.
[
{
"name" : "F1",
"children" : [
{
"name" : "F1S1"
},
{
"name" : "F1S2",
"children" : [
{
"name" : "F1S2S1"
},
{
"name" : "F1S2S2"
}
]
},
{
"name" : "F1S3"
}
]
},
{
"name" : "F2",
"children" : [
{
"name" : "F2S1"
},
{
"name" : "F2S2",
"children" : [
{
"name" : "F2S2S1"
},
{
"name" : "F2S2S2",
"children" : [
{
"name" : "F2S2S2S1"
},
{
"name" : "F2S2S2S2"
}
]
}
]
}
]
}
]
I have tried to use array.reduce method but not able to deduce proper logic. Could Someone guide me.
var data = [
["F1", "F1S1", "", ""],
["", "F1S2", "F1S2S1", ""],
["", "", "F1S2S2", ""],
["", "F1S3", "", ""],
["F2", "F2S1", "", ""],
["", "F2S2", "F2S2S1", ""],
["", "", "F2S2S2", "F2S2S2S1"],
["", "", "", "F2S2S2S2"]
]
var tree = data.reduce(function(tree, item) {
var tempTree = tree;
for (var i = 0; i < item.length; i++) {
if (!tempTree[item[i]])
tempTree[item[i]] = {};
tempTree = tempTree[item[i]];
}
return tree;
}, {});
console.log(tree)
Start by creating an n x n array of nodes and assign the numbers to the nodes. This array will contain the leaves of the tree. Then create a new two dimensional array of nodes with dimensions n/2 * n/2. For each node, assign the respective nodes of the original array as children.
With sorted data, you could take a helper array for keeping the last levels of the inserted nodes.
var data = [["F1", "F1S1", "", ""], ["", "F1S2", "F1S2S1", ""], ["", "", "F1S2S2", ""], ["", "F1S3", "", ""], ["F2", "F2S1", "", ""], ["", "F2S2", "F2S2S1", ""], ["", "", "F2S2S2", "F2S2S2S1"], ["", "", "", "F2S2S2S2"]],
result = [],
levels = [result];
data.forEach(a =>
a.forEach((name, i) => {
if (!name) return;
levels[i].push({ name, children: (levels[i + 1] = []) });
})
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you do not like to have empty children, you could check in advance and add the children before adding a new node.
var data = [["F1", "F1S1", "", ""], ["", "F1S2", "F1S2S1", ""], ["", "", "F1S2S2", ""], ["", "F1S3", "", ""], ["F2", "F2S1", "", ""], ["", "F2S2", "F2S2S1", ""], ["", "", "F2S2S2", "F2S2S2S1"], ["", "", "", "F2S2S2S2"]],
result = [],
levels = [result];
data.forEach(a =>
a.forEach((name, i) => {
if (!name) return;
if (i && !levels[i - 1][levels[i - 1].length - 1].children) {
levels[i] = [];
levels[i - 1][levels[i - 1].length - 1].children = levels[i];
}
levels[i].push({ name });
})
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With