Reputation: 7397
I am trying to Flatten JSON to parse as a CSV. But the flattening is not properly flattening. When I get the json to flatten customer.addresses is filling with addresstype:r then skipping all fields city,countrycode,countycode etc. and then starting at customer.companyName. The nested JSON is not breaking up properly to show properly in excel I think my JavaScript code must be off just a little bit. Any help with this would be greatly appreciated.
JSON (this is a portion of the nested json it will not always be in the same depth is there a way to code for any type of nested json that will read at all levels)
[
{
"countyCode": 12,
"customer": {
"addresses": [
{
"addressType": "R",
"city": "BRADENTON",
"countryCode": "US",
"countyCode": 12,
"foreignPostalCode": null,
"state": "FL",
"streetAddress": "819 15th Ave Dr E",
"zipCode": 34211,
"zipPlus": null
},
{
"addressType": "M",
"city": "BRADENTON",
"countryCode": "US",
"countyCode": 12,
"foreignPostalCode": null,
"state": "FL",
"streetAddress": "PO BOX 124",
"zipCode": 34201,
"zipPlus": 0124
}
],
"companyName": null,
"customerNumber": 932874,
"customerStopFlag": false,
"customerType": "I",
"dateOfBirth": "1936-08-05T00:00:00",
"dlExpirationDate": "2022-08-05T00:00:00",
"dlRenewalEligibilityFlag": true,
"driverLicenseNumber": "B360722339284",
"emailAddress": null,
"feidNumber": null,
"firstName": "David",
"lastName": "Brierton",
"middleName": "Hugh",
"militaryExemptionFlag": null,
"nameSuffix": null,
"sex": "M"
JS
function flatObjectToString(obj) {
var s = "";
Object.keys(obj).map(key => {
if (obj[key] === null) {
s += key + ":";
} else if (obj[key].toLocaleDateString) {
s += key + ": " + obj[key].toLocaleDateString() + "\n";
} else if (obj[key] instanceof Array) {
s += key + ":\n" + listToFlatString(obj[key]);
} else if (typeof obj[key] == "object") {
s += key + ":\n" + flatObjectToString(obj[key]);
} else {
s += key + ":" + obj[key];
}
s += "\n";
});
return s;
}
function listToFlatString(list) {
var s = "";
list.map(item => {
Object.keys(item).map(key => {
s += "";
if (item[key] instanceof Array) {
s += key + "\n" + listToFlatString(item[key]);
} else if (typeof item[key] == "object" && item[key] !== null) {
s += key + ": " + flatObjectToString(item[key]);
} else {
s += key + ": " + (item[key] === null ? "" : item[key].toLocaleDateString ? item[key].toLocaleDateString : item[key].toString());
}
s += "\n";
});
});
return s;
}
function flatten(object, addToList, prefix) {
Object.keys(object).map(key => {
if (object[key] === null) {
addToList[prefix + key] = "";
} else
if (object[key] instanceof Array) {
addToList[prefix + key] = listToFlatString(object[key]);
} else if (typeof object[key] == 'object' && !object[key].toLocaleDateString) {
flatten(object[key], addToList, prefix + key + '.');
} else {
addToList[prefix + key] = object[key];
}
});
return addToList;
}
Then I run it through the Javascript Utilities with this:
// Run the JSON string through the flattening utilities above
var flatJSON = JSON.parse(evt.target.result).map(record => flatten(record, {}, ''));
var csv = Papa.unparse(flatJSON);
Upvotes: 17
Views: 12876
Reputation: 445
function obj2csv(obj, opt) {
if (typeof obj !== 'object') return null;
opt = opt || {};
var scopechar = opt.scopechar || '.';
var delimeter = opt.delimeter || ',';
if (Array.isArray(obj) === false) obj = [obj];
var curs, name, rownum, key, queue, values = [], rows = [], headers = {}, headersArr = [];
for (rownum = 0; rownum < obj.length; rownum++) {
queue = [obj[rownum], ''];
rows[rownum] = {};
while (queue.length > 0) {
name = queue.pop();
curs = queue.pop();
if (curs !== null && typeof curs === 'object') {
for (key in curs) {
if (curs.hasOwnProperty(key)) {
queue.push(curs[key]);
queue.push(name + (name ? scopechar : '') + key);
}
}
} else {
if (headers[name] === undefined) headers[name] = true;
rows[rownum][name] = curs;
}
}
values[rownum] = [];
}
// create csv text
for (key in headers) {
if (headers.hasOwnProperty(key)) {
headersArr.push(key);
for (rownum = 0; rownum < obj.length; rownum++) {
values[rownum].push(rows[rownum][key] === undefined
? ''
: rows[rownum][key]);//JSON.stringify()
}
}
}
for (rownum = 0; rownum < obj.length; rownum++) {
values[rownum] = values[rownum].join(delimeter);
}
return '"' + headersArr.join('"' + delimeter + '"') + '"\n' + values.join('\n');
}
if you you have a json like the following
{
"_id": "template:user",
"_rev": "11-d319c4ac632171d6f01c40fdef3164a5",
"p": "user",
"first_name": "first_name_000",
"last_name": "last_name_000",
"favorite_list": {
"field": "value_000"
},
"list_kmorganisation": [
{
"siren": "siren_000",
"partition": "partition_000",
"id_role": "id_role_000",
"is_default": "is_default_000",
"is_managed": "is_managed_000",
"is_banned": "is_managed_000",
"ban_reason": "ban_reason_000",
"ban_date": "ban_date_000",
"last_connection": "last_connection_000"
}
],
"login": {
"mail": "mail_000",
"passwd": "passwd_000",
"salt": "salt_000",
"status": "status_000",
"access": [
{
"log_date": "log_date_000",
"os": "os_000",
"version": "version_000",
"ip_addr": "ip_addr_000",
"screen": "screen_000"
}
]
}
}
the end result will be flattened like this "login__access__0__screen", "login__access__0__ip_addr", "login__access__0__version", "login__access__0__os", "login__access__0__log_date", "login__status", "login__salt", "login__passwd", "login__mail", "last_name","first_name", "list_kmorganisation__1__last_connection", "list_kmorganisation__1__ban_date", "list_kmorganisation__1__ban_reason", "list_kmorganisation__1__is_banned", "list_kmorganisation__1__is_managed", "list_kmorganisation__1__is_default", "list_kmorganisation__1__id_role", "list_kmorganisation__1__partition", "list_kmorganisation__1__cmpny_name", "list_kmorganisation__1__siren", "list_kmorganisation__0__last_connection", "list_kmorganisation__0__ban_date", "list_kmorganisation__0__ban_reason", "list_kmorganisation__0__is_banned", "list_kmorganisation__0__is_managed", "list_kmorganisation__0__is_default", "list_kmorganisation__0__id_role", "list_kmorganisation__0__partition", "list_kmorganisation__0__cmpny_name", "list_kmorganisation__0__siren", "p", "_rev", "_id" (in one line of course and the values in the following line )
Upvotes: 1
Reputation: 61
Here is a solution that is readable, and that also parses dates correctly. Several solutions mentioned flattens objects recursively, but does not take into consideration that dates are objects. This is not an issue when using json files as OP mentioned, but when the same flattener-function is used on js-objects the dates will not be parsed correctly.
Prefix inserts one or more prefixes if needed ("my.prefixes.here.0.value")
export const flatten = (obj, prefix = [], current = {}) => {
const isDate = obj instanceof Date;
const isObject = typeof obj === "object";
const notNull = obj !== null;
const flattenRecursive = !isDate && isObject && notNull;
if (flattenRecursive) {
for (const key in obj) {
flatten(obj[key], prefix.concat(key), current);
}
} else {
current[prefix.join(".")] = obj;
}
return current;
};
Edit: Output from function with example-data from op:
{ '0.countyCode': 12,
'0.customer.addresses.0.addressType': 'R',
'0.customer.addresses.0.city': 'BRADENTON',
'0.customer.addresses.0.countryCode': 'US',
'0.customer.addresses.0.countyCode': 12,
'0.customer.addresses.0.foreignPostalCode': null,
'0.customer.addresses.0.state': 'FL',
'0.customer.addresses.0.streetAddress': '819 15th Ave Dr E',
'0.customer.addresses.0.zipCode': 34211,
'0.customer.addresses.0.zipPlus': null,
'0.customer.addresses.1.addressType': 'M',
'0.customer.addresses.1.city': 'BRADENTON',
'0.customer.addresses.1.countryCode': 'US',
'0.customer.addresses.1.countyCode': 12,
'0.customer.addresses.1.foreignPostalCode': null,
'0.customer.addresses.1.state': 'FL',
'0.customer.addresses.1.streetAddress': 'PO BOX 124',
'0.customer.addresses.1.zipCode': 34201,
'0.customer.addresses.1.zipPlus': '0124',
'0.customer.companyName': null,
'0.customer.customerNumber': 932874,
'0.customer.customerStopFlag': false,
'0.customer.customerType': 'I',
'0.customer.dateOfBirth': '1936-08-05T00:00:00',
'0.customer.dlExpirationDate': '2022-08-05T00:00:00',
'0.customer.dlRenewalEligibilityFlag': true,
'0.customer.driverLicenseNumber': 'B360722339284',
'0.customer.emailAddress': null,
'0.customer.feidNumber': null,
'0.customer.firstName': 'David',
'0.customer.lastName': 'Brierton',
'0.customer.middleName': 'Hugh',
'0.customer.militaryExemptionFlag': null,
'0.customer.nameSuffix': null,
'0.customer.sex': 'M' }
Upvotes: 2
Reputation: 654
I would recommend using flat and not re-inventing the wheel. If you really don't want to do that you could just read Hugh's code here. He supports both flatten and unflatten. Here is the flatten function for reference:
var isBuffer = require('is-buffer')
module.exports = flatten
flatten.flatten = flatten
flatten.unflatten = unflatten
function flatten (target, opts) {
opts = opts || {}
var delimiter = opts.delimiter || '.'
var maxDepth = opts.maxDepth
var output = {}
function step (object, prev, currentDepth) {
currentDepth = currentDepth || 1
Object.keys(object).forEach(function (key) {
var value = object[key]
var isarray = opts.safe && Array.isArray(value)
var type = Object.prototype.toString.call(value)
var isbuffer = isBuffer(value)
var isobject = (
type === '[object Object]' ||
type === '[object Array]'
)
var newKey = prev
? prev + delimiter + key
: key
if (!isarray && !isbuffer && isobject && Object.keys(value).length &&
(!opts.maxDepth || currentDepth < maxDepth)) {
return step(value, newKey, currentDepth + 1)
}
output[newKey] = value
})
}
step(target)
return output
}
Upvotes: 2
Reputation: 146510
If you are looking for the fix to your actual code then you need to use something like below
function flatten(object, addToList, prefix) {
Object.keys(object).map(key => {
if (object[key] === null) {
addToList[prefix + key] = "";
} else
if (object[key] instanceof Array) {
// addToList[prefix + key] = listToFlatString(object[key]);
for (i in object[key]) {
flatten(object[key][i], addToList, prefix + key + "." + i)
}
} else if (typeof object[key] == 'object' && !object[key].toLocaleDateString) {
flatten(object[key], addToList, prefix + key + '.');
} else {
addToList[prefix + key] = object[key];
}
});
return addToList;
}
I replace
addToList[prefix + key] = listToFlatString(object[key]);
with
for (i in object[key]) {
flatten(object[key][i], addToList, prefix + key + "." + i)
}
That fixed the issue and the output is below as per the sample json you provided
[ '0.countyCode': 12,
'0.excludedFlag': '',
'0.fees.annualTotalFees': 35.6,
'0.fees.annualTotalFeesMail': 36.35,
'0.fees.annualTotalFeesOnline': 38.35,
'0.fees.biennialTotalFees': 71.2,
'0.fees.biennialTotalFeesMail': 71.95,
'0.fees.biennialTotalFeesOnline': 73.95,
'0.fees.branchFeeFlag': false,
'0.fees.delinquentFeeAmount': 5,
'0.fees.mhBackTax': 0,
'0.fees.mhBackTaxMonths': 0,
'0.fileId': 522,
'0.id': '0002be04-546-4a92-a3d7-c31546544f',
'0.messages.0messageCode': 'RN2',
'0.messages.0messageText': 'Plate must be replaced if a 2 year renewal is desired.',
'0.messages.0messageType': 'I',
'0.messages.1messageCode': 'RN40',
'0.messages.1messageText': 'You must complete the affidavit on the reverse side or provide a copy of your Florida insurance identification card.',
'0.messages.1messageType': 'I',
'0.messages.2messageCode': 'RN41',
'0.messages.2messageText': 'Insurance is on file.',
'0.messages.2messageType': 'II',
'0.registrationDetail.annualPlateReplacementFlag': false,
'0.registrationDetail.arfCredit': 25.6,
'0.registrationDetail.biennialPlateReplacementFlag': true,
'0.registrationDetail.customerStopFlag': '',
'0.registrationDetail.delinquentDate': '2018-02-11T00:00:00',
'0.registrationDetail.expirationDate': '2018-01-09T00:00:00',
'0.registrationDetail.foreignAddressFlag': false,
'0.registrationDetail.honorayConsulPlateFlag': '',
'0.registrationDetail.hovDecalNumber': '',
'0.registrationDetail.hovDecalYear': '',
'0.registrationDetail.hovExpirationDate': '',
'0.registrationDetail.inventorySubtype': 'RP',
'0.registrationDetail.lastActivityCounty': 12,
'0.registrationDetail.legislativePlateDueForReplacementFlag': false,
'0.registrationDetail.licensePlateCode': 'RGR',
'0.registrationDetail.licensePlateNumber': 'L45656',
'0.registrationDetail.mailToAddressFlag': false,
'0.registrationDetail.mailToCustomerNumber': '',
'0.registrationDetail.mhLocationCode': '',
'0.registrationDetail.militaryOwnerFlag': false,
'0.registrationDetail.numberOfRegistrants': 1,
'0.registrationDetail.onlineRenewalEligibilityFlag': true,
'0.registrationDetail.pinNumber': 222354654,
'0.registrationDetail.plateExpirationDate': '2018-03-18T00:00:00',
'0.registrationDetail.plateIssueDate': '2008-09-18T00:00:00',
'0.registrationDetail.possibleNgExemptionFlag': false,
'0.registrationDetail.registrationNumber': 2234545345,
'0.registrationDetail.registrationOnlyFlag': '',
'0.registrationDetail.registrationType': 'R',
'0.registrationDetail.registrationUse': 'PR',
'0.registrationDetail.renewalCountyCode': 12,
'0.registrationDetail.rentalParkFlag': '',
'0.registrationDetail.seminoleMiccosukeeIndianFlag': false,
'0.registrationDetail.taxCollectorRenewalEligibilityFlag': true,
'0.registrationDetail.vehicleClassCode': 1,
'0.registrationOwners.0customer.addresses.0addressType': 'R',
'0.registrationOwners.0customer.addresses.0city': 'PALMETTO',
'0.registrationOwners.0customer.addresses.0countryCode': 'US',
'0.registrationOwners.0customer.addresses.0countyCode': 12,
'0.registrationOwners.0customer.addresses.0foreignPostalCode': '',
'0.registrationOwners.0customer.addresses.0state': 'FL',
'0.registrationOwners.0customer.addresses.0streetAddress': '34545 7TH AVE W',
'0.registrationOwners.0customer.addresses.0zipCode': 34221,
'0.registrationOwners.0customer.addresses.0zipPlus': '',
'0.registrationOwners.0customer.addresses.1addressType': 'M',
'0.registrationOwners.0customer.addresses.1city': 'PALMETTO',
'0.registrationOwners.0customer.addresses.1countryCode': 'US',
'0.registrationOwners.0customer.addresses.1countyCode': 12,
'0.registrationOwners.0customer.addresses.1foreignPostalCode': '',
'0.registrationOwners.0customer.addresses.1state': 'FL',
'0.registrationOwners.0customer.addresses.1streetAddress': '34545 7TH AVE W',
'0.registrationOwners.0customer.addresses.1zipCode': 34221,
'0.registrationOwners.0customer.addresses.1zipPlus': 3433,
'0.registrationOwners.0customer.companyName': '',
'0.registrationOwners.0customer.customerNumber': 3346645,
'0.registrationOwners.0customer.customerStopFlag': false,
'0.registrationOwners.0customer.customerType': 'I',
'0.registrationOwners.0customer.dateOfBirth': '1971-01-09T00:00:00',
'0.registrationOwners.0customer.dlExpirationDate': '2025-01-09T00:00:00',
'0.registrationOwners.0customer.dlRenewalEligibilityFlag': true,
'0.registrationOwners.0customer.driverLicenseNumber': 'F34545345345',
'0.registrationOwners.0customer.emailAddress': '',
'0.registrationOwners.0customer.feidNumber': '',
'0.registrationOwners.0customer.firstName': 'DAVID',
'0.registrationOwners.0customer.lastName': 'HUGH',
'0.registrationOwners.0customer.middleName': 'BRIERTON',
'0.registrationOwners.0customer.militaryExemptionFlag': false,
'0.registrationOwners.0customer.nameSuffix': '',
'0.registrationOwners.0customer.sex': 'F',
'0.registrationOwners.0registrationOwnershipNumber': 1,
'0.shippingAddress.address.addressType': 'S',
'0.shippingAddress.address.city': 'PALMETTO',
'0.shippingAddress.address.countryCode': 'US',
'0.shippingAddress.address.countyCode': 12,
'0.shippingAddress.address.foreignPostalCode': '',
'0.shippingAddress.address.state': 'FL',
'0.shippingAddress.address.streetAddress': '34545 7TH AVE W',
'0.shippingAddress.address.zipCode': 34221,
'0.shippingAddress.address.zipPlus': 8344,
'0.shippingAddress.shippingCompanyName': '',
'0.shippingAddress.shippingName1': 'DAVID HUGH BRIERTON',
'0.shippingAddress.shippingName2': '',
'0.stops': '',
'0.vehicle.address': '',
'0.vehicle.bodyCode': '4D',
'0.vehicle.brakeHorsePower': '',
'0.vehicle.cubicCentimeters': '',
'0.vehicle.grossWeight': '',
'0.vehicle.insuranceAffidavitCode': '',
'0.vehicle.leaseOwnerFlag': false,
'0.vehicle.lengthFeet': '',
'0.vehicle.lengthInches': '',
'0.vehicle.majorColorCode': 'GLD',
'0.vehicle.makeCode': 'CHEV',
'0.vehicle.minorColorCode': '',
'0.vehicle.netWeight': 3200,
'0.vehicle.numberOfAxles': '',
'0.vehicle.ownerUnitNumber': '',
'0.vehicle.titleNumber': 345454534,
'0.vehicle.vehicleIdentificationNumber': '1G1ZD345U5B345435',
'0.vehicle.vehicleNumber': 23454656,
'0.vehicle.vehicleType': 'AU',
'0.vehicle.vesselCode': '',
'0.vehicle.vesselManufacturerDesc': '',
'0.vehicle.vesselResidentStatus': 'Y',
'0.vehicle.vesselWaterType': '',
'0.vehicle.widthFeet': '',
'0.vehicle.widthInches': '',
'0.vehicle.yearMake': 2011,
'1.countyCode': 12,
'1.excludedFlag': '',
'1.fees.annualTotalFees': 27.6,
'1.fees.annualTotalFeesMail': 28.35,
'1.fees.annualTotalFeesOnline': 30.35,
'1.fees.biennialTotalFees': 55.2,
'1.fees.biennialTotalFeesMail': 55.95,
'1.fees.biennialTotalFeesOnline': 57.95,
'1.fees.branchFeeFlag': false,
'1.fees.delinquentFeeAmount': 5,
'1.fees.mhBackTax': 0,
'1.fees.mhBackTaxMonths': 0,
'1.fileId': 522,
'1.id': '0008c654-8960-45b8-b416-cff3456767',
'1.messages.0messageCode': 'RN40',
'1.messages.0messageText': 'You must complete the affidavit on the reverse side or provide a copy of your Florida insurance identification card.',
'1.messages.0messageType': 'I',
'1.registrationDetail.annualPlateReplacementFlag': false,
'1.registrationDetail.arfCredit': 2.8,
'1.registrationDetail.biennialPlateReplacementFlag': false,
'1.registrationDetail.customerStopFlag': '',
'1.registrationDetail.delinquentDate': '2018-02-11T00:00:00',
'1.registrationDetail.expirationDate': '2018-01-01T00:00:00',
'1.registrationDetail.foreignAddressFlag': false,
'1.registrationDetail.honorayConsulPlateFlag': '',
'1.registrationDetail.hovDecalNumber': '',
'1.registrationDetail.hovDecalYear': '',
'1.registrationDetail.hovExpirationDate': '',
'1.registrationDetail.inventorySubtype': 'SS',
'1.registrationDetail.lastActivityCounty': 16,
'1.registrationDetail.legislativePlateDueForReplacementFlag': false,
'1.registrationDetail.licensePlateCode': 'RGS',
'1.registrationDetail.licensePlateNumber': 'HU34598',
'1.registrationDetail.mailToAddressFlag': false,
'1.registrationDetail.mailToCustomerNumber': '',
'1.registrationDetail.mhLocationCode': '',
'1.registrationDetail.militaryOwnerFlag': false,
'1.registrationDetail.numberOfRegistrants': 1,
'1.registrationDetail.onlineRenewalEligibilityFlag': true,
'1.registrationDetail.pinNumber': 4936856,
'1.registrationDetail.plateExpirationDate': '2026-09-24T00:00:00',
'1.registrationDetail.plateIssueDate': '2017-03-24T00:00:00',
'1.registrationDetail.possibleNgExemptionFlag': false,
'1.registrationDetail.registrationNumber': 4095685,
'1.registrationDetail.registrationOnlyFlag': '',
'1.registrationDetail.registrationType': 'R',
'1.registrationDetail.registrationUse': 'PR',
'1.registrationDetail.renewalCountyCode': 12,
'1.registrationDetail.rentalParkFlag': '',
'1.registrationDetail.seminoleMiccosukeeIndianFlag': false,
'1.registrationDetail.taxCollectorRenewalEligibilityFlag': true,
'1.registrationDetail.vehicleClassCode': 1,
'1.registrationOwners.0customer.addresses.0addressType': 'R',
'1.registrationOwners.0customer.addresses.0city': 'SARASOTA',
'1.registrationOwners.0customer.addresses.0countryCode': 'US',
'1.registrationOwners.0customer.addresses.0countyCode': 12,
'1.registrationOwners.0customer.addresses.0foreignPostalCode': '',
'1.registrationOwners.0customer.addresses.0state': 'FL',
'1.registrationOwners.0customer.addresses.0streetAddress': '5858 FRUITVILLE RD',
'1.registrationOwners.0customer.addresses.0zipCode': 34240,
'1.registrationOwners.0customer.addresses.0zipPlus': 5858,
'1.registrationOwners.0customer.addresses.1addressType': 'M',
'1.registrationOwners.0customer.addresses.1city': 'SARASOTA',
'1.registrationOwners.0customer.addresses.1countryCode': 'US',
'1.registrationOwners.0customer.addresses.1countyCode': 16,
'1.registrationOwners.0customer.addresses.1foreignPostalCode': '',
'1.registrationOwners.0customer.addresses.1state': 'FL',
'1.registrationOwners.0customer.addresses.1streetAddress': '5858 FRUITVILLE RD',
'1.registrationOwners.0customer.addresses.1zipCode': 34240,
'1.registrationOwners.0customer.addresses.1zipPlus': 5858,
'1.registrationOwners.0customer.companyName': '',
'1.registrationOwners.0customer.customerNumber': 2928357,
'1.registrationOwners.0customer.customerStopFlag': false,
'1.registrationOwners.0customer.customerType': 'I',
'1.registrationOwners.0customer.dateOfBirth': '1989-01-01T00:00:00',
'1.registrationOwners.0customer.dlExpirationDate': '2022-01-01T00:00:00',
'1.registrationOwners.0customer.dlRenewalEligibilityFlag': true,
'1.registrationOwners.0customer.driverLicenseNumber': 'B94832734',
'1.registrationOwners.0customer.emailAddress': '',
'1.registrationOwners.0customer.feidNumber': '',
'1.registrationOwners.0customer.firstName': 'DAVID1',
'1.registrationOwners.0customer.lastName': 'HUGH1',
'1.registrationOwners.0customer.middleName': 'BRIERTON1',
'1.registrationOwners.0customer.militaryExemptionFlag': false,
'1.registrationOwners.0customer.nameSuffix': '',
'1.registrationOwners.0customer.sex': 'M',
'1.registrationOwners.0registrationOwnershipNumber': 1,
'1.shippingAddress.address.addressType': 'S',
'1.shippingAddress.address.city': 'SARASOTA',
'1.shippingAddress.address.countryCode': 'US',
'1.shippingAddress.address.countyCode': 16,
'1.shippingAddress.address.foreignPostalCode': '',
'1.shippingAddress.address.state': 'FL',
'1.shippingAddress.address.streetAddress': '5858 FRUITVILLE RD',
'1.shippingAddress.address.zipCode': 34240,
'1.shippingAddress.address.zipPlus': 5858,
'1.shippingAddress.shippingCompanyName': '',
'1.shippingAddress.shippingName1': 'DAVID1 HUGH1 BRIERTON1',
'1.shippingAddress.shippingName2': '',
'1.stops': '',
'1.vehicle.address': '',
'1.vehicle.bodyCode': '4D',
'1.vehicle.brakeHorsePower': '',
'1.vehicle.cubicCentimeters': '',
'1.vehicle.grossWeight': '',
'1.vehicle.insuranceAffidavitCode': '',
'1.vehicle.leaseOwnerFlag': false,
'1.vehicle.lengthFeet': '',
'1.vehicle.lengthInches': '',
'1.vehicle.majorColorCode': 'BLU',
'1.vehicle.makeCode': 'STRN',
'1.vehicle.minorColorCode': '',
'1.vehicle.netWeight': 2290,
'1.vehicle.numberOfAxles': '',
'1.vehicle.ownerUnitNumber': '',
'1.vehicle.titleNumber': 239874,
'1.vehicle.vehicleIdentificationNumber': '1G832492871Z23094',
'1.vehicle.vehicleNumber': 239084,
'1.vehicle.vehicleType': 'AU',
'1.vehicle.vesselCode': '',
'1.vehicle.vesselManufacturerDesc': '',
'1.vehicle.vesselResidentStatus': 'Y',
'1.vehicle.vesselWaterType': '',
'1.vehicle.widthFeet': '',
'1.vehicle.widthInches': '',
'1.vehicle.yearMake': 2001,
'2.countyCode': 12,
'2.excludedFlag': '',
'2.fees.annualTotalFees': 45.6,
'2.fees.annualTotalFeesMail': 46.35,
'2.fees.annualTotalFeesOnline': 48.35,
'2.fees.biennialTotalFees': 91.2,
'2.fees.biennialTotalFeesMail': 91.95,
'2.fees.biennialTotalFeesOnline': 93.95,
'2.fees.branchFeeFlag': false,
'2.fees.delinquentFeeAmount': 10,
'2.fees.mhBackTax': 0,
'2.fees.mhBackTaxMonths': 0,
'2.fileId': 522,
'2.id': '000e3450d-3454-499a-ae70-de5676577',
'2.messages.0messageCode': 'RN40',
'2.messages.0messageText': 'You must complete the affidavit on the reverse side or provide a copy of your Florida insurance identification card.',
'2.messages.0messageType': 'I',
'2.registrationDetail.annualPlateReplacementFlag': false,
'2.registrationDetail.arfCredit': 8.4,
'2.registrationDetail.biennialPlateReplacementFlag': false,
'2.registrationDetail.customerStopFlag': '',
'2.registrationDetail.delinquentDate': '2018-02-11T00:00:00',
'2.registrationDetail.expirationDate': '2018-01-11T00:00:00',
'2.registrationDetail.foreignAddressFlag': false,
'2.registrationDetail.honorayConsulPlateFlag': '',
'2.registrationDetail.hovDecalNumber': '',
'2.registrationDetail.hovDecalYear': '',
'2.registrationDetail.hovExpirationDate': '',
'2.registrationDetail.inventorySubtype': 'RP',
'2.registrationDetail.lastActivityCounty': 12,
'2.registrationDetail.legislativePlateDueForReplacementFlag': false,
'2.registrationDetail.licensePlateCode': 'RGR',
'2.registrationDetail.licensePlateNumber': '808IUT',
'2.registrationDetail.mailToAddressFlag': false,
'2.registrationDetail.mailToCustomerNumber': '',
'2.registrationDetail.mhLocationCode': '',
'2.registrationDetail.militaryOwnerFlag': false,
'2.registrationDetail.numberOfRegistrants': 1,
'2.registrationDetail.onlineRenewalEligibilityFlag': true,
'2.registrationDetail.pinNumber': 934597,
'2.registrationDetail.plateExpirationDate': '2023-06-06T00:00:00',
'2.registrationDetail.plateIssueDate': '2013-12-06T00:00:00',
'2.registrationDetail.possibleNgExemptionFlag': false,
'2.registrationDetail.registrationNumber': 39287432,
'2.registrationDetail.registrationOnlyFlag': '',
'2.registrationDetail.registrationType': 'R',
'2.registrationDetail.registrationUse': 'PR',
'2.registrationDetail.renewalCountyCode': 12,
'2.registrationDetail.rentalParkFlag': '',
'2.registrationDetail.seminoleMiccosukeeIndianFlag': false,
'2.registrationDetail.taxCollectorRenewalEligibilityFlag': true,
'2.registrationDetail.vehicleClassCode': 1,
'2.registrationOwners.0customer.addresses.0addressType': 'R',
'2.registrationOwners.0customer.addresses.0city': 'SARASOTA',
'2.registrationOwners.0customer.addresses.0countryCode': 'US',
'2.registrationOwners.0customer.addresses.0countyCode': 12,
'2.registrationOwners.0customer.addresses.0foreignPostalCode': '',
'2.registrationOwners.0customer.addresses.0state': 'FL',
'2.registrationOwners.0customer.addresses.0streetAddress': '39875 44TH DR E',
'2.registrationOwners.0customer.addresses.0zipCode': 34243,
'2.registrationOwners.0customer.addresses.0zipPlus': 5566,
'2.registrationOwners.0customer.addresses.1addressType': 'M',
'2.registrationOwners.0customer.addresses.1city': 'PALMETTO',
'2.registrationOwners.0customer.addresses.1countryCode': 'US',
'2.registrationOwners.0customer.addresses.1countyCode': 12,
'2.registrationOwners.0customer.addresses.1foreignPostalCode': '',
'2.registrationOwners.0customer.addresses.1state': 'FL',
'2.registrationOwners.0customer.addresses.1streetAddress': '39875 44TH DR E',
'2.registrationOwners.0customer.addresses.1zipCode': 34221,
'2.registrationOwners.0customer.addresses.1zipPlus': '',
'2.registrationOwners.0customer.companyName': '',
'2.registrationOwners.0customer.customerNumber': 2398574,
'2.registrationOwners.0customer.customerStopFlag': false,
'2.registrationOwners.0customer.customerType': 'I',
'2.registrationOwners.0customer.dateOfBirth': '1958-01-11T00:00:00',
'2.registrationOwners.0customer.dlExpirationDate': '2020-01-11T00:00:00',
'2.registrationOwners.0customer.dlRenewalEligibilityFlag': true,
'2.registrationOwners.0customer.driverLicenseNumber': 'B23987433',
'2.registrationOwners.0customer.emailAddress': '',
'2.registrationOwners.0customer.feidNumber': '',
'2.registrationOwners.0customer.firstName': 'DAVID2',
'2.registrationOwners.0customer.lastName': 'HUGH2',
'2.registrationOwners.0customer.middleName': 'BRIERTON2',
'2.registrationOwners.0customer.militaryExemptionFlag': false,
'2.registrationOwners.0customer.nameSuffix': '',
'2.registrationOwners.0customer.sex': 'M',
'2.registrationOwners.0registrationOwnershipNumber': 1,
'2.shippingAddress.address.addressType': 'S',
'2.shippingAddress.address.city': 'PALMETTO',
'2.shippingAddress.address.countryCode': 'US',
'2.shippingAddress.address.countyCode': 12,
'2.shippingAddress.address.foreignPostalCode': '',
'2.shippingAddress.address.state': 'FL',
'2.shippingAddress.address.streetAddress': '293847 33TH ST W',
'2.shippingAddress.address.zipCode': 34221,
'2.shippingAddress.address.zipPlus': '',
'2.shippingAddress.shippingCompanyName': '',
'2.shippingAddress.shippingName1': 'DAVID2 HUGH2 BRIERTON2',
'2.shippingAddress.shippingName2': '',
'2.stops': '',
'2.vehicle.address': '',
'2.vehicle.bodyCode': '2D',
'2.vehicle.brakeHorsePower': '',
'2.vehicle.cubicCentimeters': '',
'2.vehicle.grossWeight': '',
'2.vehicle.insuranceAffidavitCode': '',
'2.vehicle.leaseOwnerFlag': false,
'2.vehicle.lengthFeet': '',
'2.vehicle.lengthInches': '',
'2.vehicle.majorColorCode': 'BLK',
'2.vehicle.makeCode': 'PONT',
'2.vehicle.minorColorCode': '',
'2.vehicle.netWeight': 3802,
'2.vehicle.numberOfAxles': '',
'2.vehicle.ownerUnitNumber': '',
'2.vehicle.titleNumber': 239857424,
'2.vehicle.vehicleIdentificationNumber': '6G23242312UX63297437',
'2.vehicle.vehicleNumber': '35T7843',
'2.vehicle.vehicleType': 'AU',
'2.vehicle.vesselCode': '',
'2.vehicle.vesselManufacturerDesc': '',
'2.vehicle.vesselResidentStatus': 'Y',
'2.vehicle.vesselWaterType': '',
'2.vehicle.widthFeet': '',
'2.vehicle.widthInches': '',
'2.vehicle.yearMake': 2006 ]
Upvotes: 10
Reputation: 896
Another solution:
function flatObjectToString(obj) {
var path = [],
nodes = {},
parseObj = function (obj) {
if (typeof obj == 'object') {
if (obj instanceof Array) { //array
for (var i = 0, l = obj.length; i < l; i++) {
path.push(i);
parseObj(obj[i]);
path.pop();
}
}
else { //object
for (var node in obj) {
path.push(node);
parseObj(obj[node]);
path.pop();
}
}
}
else { //value
nodes[path.join('_')] = obj;
}
};
parseObj(obj);
return nodes;
}
console.log(JSON.stringify(flatObjectToString(data)));
Upvotes: 3
Reputation: 146510
You can use something like below
data = require("./data.json")
flattenObject = (obj) => {
let flattenKeys = {};
for (let i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if ((typeof obj[i]) == 'object') {
// flattenKeys[i] = obj[i];
let flatObject = flattenObject(obj[i]);
for (let j in flatObject) {
if (!flatObject.hasOwnProperty(j)) continue;
flattenKeys[i + '.' + j] = flatObject[j];
}
} else {
flattenKeys[i] = obj[i];
}
}
return flattenKeys;
}
console.log(flattenObject(data))
The output on first element of your array object is as below
{ countyCode: 12,
'customer.addresses.0.addressType': 'R',
'customer.addresses.0.city': 'BRADENTON',
'customer.addresses.0.countryCode': 'US',
'customer.addresses.0.countyCode': 12,
'customer.addresses.0.state': 'FL',
'customer.addresses.0.streetAddress': '819 15th Ave Dr E',
'customer.addresses.0.zipCode': 34211,
'customer.addresses.1.addressType': 'M',
'customer.addresses.1.city': 'BRADENTON',
'customer.addresses.1.countryCode': 'US',
'customer.addresses.1.countyCode': 12,
'customer.addresses.1.state': 'FL',
'customer.addresses.1.streetAddress': 'PO BOX 124',
'customer.addresses.1.zipCode': 34201,
'customer.addresses.1.zipPlus': '124',
'customer.customerNumber': 932874,
'customer.customerStopFlag': false,
'customer.customerType': 'I',
'customer.dateOfBirth': '1936-08-05T00:00:00',
'customer.dlExpirationDate': '2022-08-05T00:00:00',
'customer.dlRenewalEligibilityFlag': true,
'customer.driverLicenseNumber': 'B360722339284',
'customer.firstName': 'David',
'customer.lastName': 'Brierton',
'customer.middleName': 'Hugh',
'customer.sex': 'M' }
Upvotes: 8