I have a raw data that looks like that :
{SKT_CD:01582030,SKT_DATE:2021/04/12,SKT_TIME:21,SO2:0,NO:0,NO2:0.002,NOX:0.003,CO:,OX:,NMHC:,CH4:,THC:,SPM:0.008,PM2_5:,SP:},{SKT_CD:01582030,SKT_DATE:2021/04/12,SKT_TIME:22,SO2:0,NO:0,NO2:0.002,NOX:0.002,CO:,OX:,NMHC:,CH4:,THC:,SPM:0.010,PM2_5:,SP:}, and more
I need to fill those empty values to be able to use it as an object. It’s not me who create it, I got it from an external source. I know how to fill those empty values if they were like “” or null. Sometime there is a coma after the empty value and sometime nothing like for the last key. I’m a beginner and I can’t figure a way of doing that. Is that even possible?
Advertisement
Answer
Updated response
If you data looks like that, you need to change your algorithm for parsing. Just remove the leading opening-brace and ending closing-brace and split by /},s*{/
.
const rawData = `{SKT_CD:01582030,SKT_DATE:2021/04/12,SKT_TIME:21,SO2:0,NO:0,NO2:0.002,NOX:0.003,CO:,OX:,NMHC:,CH4:,THC:,SPM:0.008,PM2_5:,SP:},{SKT_CD:01582030,SKT_DATE:2021/04/12,SKT_TIME:22,SO2:0,NO:0,NO2:0.002,NOX:0.002,CO:,OX:,NMHC:,CH4:,THC:,SPM:0.010,PM2_5:,SP:}`; const obj = rawData .substring(rawData.indexOf('{') + 1, rawData.lastIndexOf('}')) .split(/},s*{/) .map(line => Object.fromEntries(line.split(/,(?=w+:)/g) .map(pair => pair.split(/(?<=^w+):/)) .filter(([key, value]) => value) .map(([key, value]) => [key, value ? !isNaN(value) ? Number(value) : value : null]))) console.log(obj);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Original response
If you need to convert this non-JSON compliant data to a JavaScript object, you could split the lines and reduce them with an object.
You can split the key-value pairs after trimming and removing the end commas. I used a positive look-behind to check for an alphanumeric sequence of characters prior to the colon.
const rawData = `{ SKT_CD:01101010, SKT_DATE:2021/04/01, SKT_TIME:01, SO2:0, NO:0, NO2:0.006, NOX:0.006, CO:, OX:0.039, NMHC:0.07, CH4:2.01, THC:2.08, SPM:0.008, PM2_5:0, SP: }`; const obj = rawData .substring(rawData.indexOf('{') + 1, rawData.lastIndexOf('}')) .trim() .split('n') .reduce((acc, line) => (([key, value]) => ({ ...acc, [key]: value ? !isNaN(value) ? Number(value) : value : null })) (line.trim().replace(/,$/, '').split(/(?<=^w+):/)), {}); console.log(obj);
.as-console-wrapper { top: 0; max-height: 100% !important; }
If you need to filter-out the pairs with an empty value, you can map prior to filtering and converting to to an object (from entries).
const rawData = `{ SKT_CD:01101010, SKT_DATE:2021/04/01, SKT_TIME:01, SO2:0, NO:0, NO2:0.006, NOX:0.006, CO:, OX:0.039, NMHC:0.07, CH4:2.01, THC:2.08, SPM:0.008, PM2_5:0, SP: }`; const obj = Object.fromEntries(rawData .substring(rawData.indexOf('{') + 1, rawData.lastIndexOf('}')) .trim() .split('n') .map((line) => (([key, value]) => [key, value ? !isNaN(value) ? Number(value) : value : null]) (line.trim().replace(/,$/, '').split(/(?<=^w+):/))) .filter(([key, value]) => value != null)); console.log(obj);
.as-console-wrapper { top: 0; max-height: 100% !important; }