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?
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; }