I have an array of objects similar to the below:
const data = [
{ "name": "Amsterdam", value: 40000, uniqueId: '2432g53122141' },
{ "name": "New York", value: 200000, uniqueId: '24322141' },
{ "name": "Mumbai", value: 5000, uniqueId: '9999' }
]
I want to convert it to the below format using tab separated strings with proper formatting/alignment similar to below.
This is needed to be a string as I will be sending this data to a third party form which accepts only text and no HTML data.
Name Value UniqueId
Amsterdam 40000 243253122141
New York 200000 24322141
Mumbai 5000 9999
How can I achieve the same with proper formatting so that there is no alignment issues as the length of data for each property can vary as can be seen above. Is there any package available?
padEnd the values to the max length for that key -> join them with a \t get each row value. Loop the properties in the same order as maxLength object in case the properties are missing / or are in different orderjoin each row with a \n to get the table body.\n to get the output.This works for any number of properties, missing properties, properties in different order, null values
const data = [
{ "name": "Amsterdam", value: 40000, uniqueId: '2432g53122141' },
{ "name": "New York", value: 200000, uniqueId: '24322141' },
{ "name": "Mumbai", value: 5000, uniqueId: '9999' }
]
const maxLength = {}
for (const o of data) {
for (const key in o)
maxLength[key] = Math.max(maxLength[key] ?? 0, String(o[key] ?? '').length)
}
console.log(maxLength)
const headers = Object.entries(maxLength)
.map(([k, length]) => k.padEnd(length))
.join("\t")
const rows = data.map(o =>
Object.entries(maxLength)
.map(([k, length]) => String(o[k] ?? '').padEnd(length))
.join('\t')
).join('\n')
console.log( [headers, rows].join('\n') )
you can do something like this
const data = [
{ "name": "Amsterdam", value: 40000, uniqueId: '2432g53122141' },
{ "name": "New York", value: 200000, uniqueId: '24322141' },
{ "name": "Mumbai", value: 5000, uniqueId: '9999' }
]
const header = Object.keys(data[0])
const rows = [header, ...data.map(d => Object.values(d))]
const maxLength = Math.max(...rows.flat().map(s => s.toString().length))
const result = rows.map(d => d.map(s => s.toString().padEnd(maxLength, ' ')).join('\t')).join('\n')
console.log(result)
This is just an example of how you could do it. You could read all the attributes of the json and then try to generate the lines. In order to do the identation I took the largest string in the json and use it as an identation length
function tabify(data) {
var columns=new Set()
//Get all the colums
for(var index in data){
for(var iKey in Object.keys(data[index]))
columns.add(Object.keys(data[index])[iKey])
}
var maxLength = 0
//Search maxLength
for (var index in data) {
columns.forEach((element) => {
if (maxLength < element.length)
maxLength = element.length
if (maxLength < data[index][element].length)
maxLength = data[index][element].length
});
}
var outText = ""
//Generate column line
columns.forEach((element) => {
outText += element
outText += Array((maxLength - element.length) + 1).join(" ")
});
outText += "\n"
//Generate the text formated
for (var index in data) {
columns.forEach((element) => {
outText += data[index][element]
outText += Array((maxLength - (data[index][element].toString()).length) + 1).join(" ")
});
outText += "\n"
}
return outText
}
let dataJson = [{
"name": "Amsterdam",
value: 40000,
uniqueId: '2432g53122141'
},
{
"name": "New York",
value: 200000,
uniqueId: '24322141'
},
{
"name": "Mumbai",
value: 5000,
uniqueId: '9999'
}
]
text = tabify(dataJson)
console.log(text)