代码之家  ›  专栏  ›  技术社区  ›  Dave M.

如何将数据记录器结果格式化为JSON?

  •  0
  • Dave M.  · 技术社区  · 4 年前

    我有一个记录时间、状态和时间的数据记录器;通过附加到文件来控制温度。(从cron作业调用记录器。)

    如果我能将数据作为JSON读入网页脚本,那就太好了,但我看不到一个好方法——要么我的记录器更复杂,要么我的阅读器更复杂。

    我的数据是这样的:

    [ timestamp, "status", temperature ]
    [ 123456789, "sync",   12345]
    

    我可以很容易地在行尾添加逗号,但不管怎样,它都不是格式良好的JSON——你需要用括号括起来。

    因此,要么我的记录器必须检测到一个空数据文件并添加一个前导括号,再加上结尾处的seek,备份一个字符,用逗号替换最后一个右括号,然后用一个额外的右括号附加它自己的记录,要么阅读器必须通过切掉一个尾随逗号并在其周围添加括号来处理前JSON。

    有更简单的方法吗?

    2 回复  |  直到 4 年前
        1
  •  1
  •   jsejcksn    4 年前

    您使用的格式与已建立的格式类似,并且非常适合于日志记录:请参阅 JSON Lines 和 ndjson .

    通过在第一行之后切片您的输入,您将得到JSON行。然后,您只需要迭代这些行并解析每一行(如果需要,可以选择收集到一个数组中)。

    下面是一个例子:

    const LF = '\n';
    
    function iterateJSONLines (jsonl, cb) {
      for (const line of jsonl.trim().split(LF)) {
        cb(JSON.parse(line));
      }
    }
    
    /** handle the first (non-JSON) line in your input */
    function separateHeaderFromJSONLines (input) {
      for (let i = 0; i < input.length; i += 1) {
        if (input[i] !== LF) continue;
        return [input.slice(0, i).trim(), input.slice(i + 1)];
      }
    }
    
    function main (input) {
      const [headerLine, jsonl] = separateHeaderFromJSONLines(input);
      const arr = [];
      iterateJSONLines(jsonl, arr.push.bind(arr));
      console.log(headerLine);
      console.log(arr);
    }
    
    const input = `[ timestamp, "status", temperature ]
    [ 123456789, "sync",   12345]
    [ 987654321, "anotherStatus",   54321]
    `;
    
    main(input);
        2
  •  0
  •   mplungjan    4 年前

    你能做到的

    我会用 fetch

    const str = `[ timestamp, "status", temperature ]
    [ 123456789, "sync",   12345]`
    
    const data = str.split(/\r?\n/) // line feed
      .map(line => line
        .replace(/[\[\]]/g,"") // remove square brackets (can be done in the regex below too
        .match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) // find stuff with or without quotes
        .map(elem => isNaN(elem) ? elem : +elem) // convert numbers back to numbers
      );
    console.log(data)