Skip to content
Advertisement

Fill the empty values in my JSON (not null or “”)

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; }
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement