Home > Software engineering >  Rescript manipulate JSON file
Rescript manipulate JSON file

Time:10-22

I have this JSON file. Using rescript I want to :

  • Read the file.
  • Extract data from the file.
  • Write result in a new file.
   {
       "name": "name",
       "examples": [
           {
               "input": [1,2],
               "result": 1
           },
           {
               "input": [3,4],
               "result": 3
           }
       ],
   }

I was able to acheive this using JavaScript

var file = Fs.readFileSync("file.json", "utf8");
var data = JSON.parse(file);
var name = data.name
var examples = data.examples
for (let i = 0; i< examples.length; i  ){
    let example = examples[i]
    let input = example.input
    let result = example.result

    let finalResult = `example ${name}, ${input[0]}, ${input[1]}, ${result} \n`
    Fs.appendFileSync('result.txt',finalResult)
}

These are my attempts at writing it in Rescript and the issues I ran into.

let file = Node.Fs.readFileSync("file.json", #utf8)
let data = Js.Json.parseExn(file)
let name = data.name  //this doesn't work. The record field name can't be found

So I have tried a different approach (which is a little bit limited because I am specifying the type of the data that I want to extract).

@module("fs")
external readFileSync: (
  ~name: string,
   [#utf8],
) => string = "readFileSync"

type data = {name: string, examples: array<Js_dict.t<t>>}

@scope("JSON") @val
external parseIntoMyData: string => data = "parse"

let file = readFileSync(~name="file.json", #utf8)
let parsedData = parseIntoMyData(file)
let name = parsedData.name
let example = parsedData.examples[0]
let input = parsedData.examples[0].input //this wouldn't work

Also tried to use Node.Fs.appendFileSync(...) and I get The value appendFileSync can't be found in Node.Fs

Is there another way to accomplish this?

CodePudding user response:

It's not clear to me why you're using Js.Dict.t<t> for your examples, and what the t in that type refers to. You certainly could use a Js.Dict.t here, and that might make sense if the shape of the data isn't static, but then you'd have to access the data using Js.Dict.get. Seems you want to use record field access instead, and if the data structure is static you can do so if you just define the types properly. From the example you give, it looks like these type definitions should accomplish what you want:

type example {
  input: (int, int), // or array<int> if it's not always two elements
  result: int,
}

type data = {
  name: string,
  examples: array<example>,
}
  • Related