2

I have (n) number of JSON files in a specific folder:

For simplicity lets assume 3 JSON files Animal.json, Noun.json, POS.JSON

and their contents respectively are

Animal.json

[
  {
    "label": "Dinosaur",
    "sample": ["#Noun Rex","saurus"]
  },
  {
    "label": "Lion",
    "sample": ["simba"]
  },
  {
    "label": "Tiger",
    "sample": ["big cat"]
  }
]

Noun.json

[
      {
        "label": "Animal",
        "sample": ["Herbivore","Carnivore"]
      }
]

POS.json

[
          {
            "label": "Noun",
            "sample": ["Proper","Common"]
          }
    ]

I want to be able to loop through all the JSON files in a specific folder and dynamically build a JSON in the below format

label: {
      Dinosaur: {
        isA: 'Animal'
      },
      Lion: {
        isA: 'Animal'
      },
      Tiger: {
        isA: 'Animal'
      },
      Animal: {
        isA: 'Noun'
      },
      Noun: {
      isA: 'POS'
      }
    },
    sample: {
      '#Noun rex|saurus': 'Dinosaur',
      'simba': 'Lion'
      'big cat': 'Tiger',
      'Herbivore|Carnivore' : 'Animal',
      'Proper|Common' : 'Noun'

    }

Logic I have so far :

function buildJSON() {
  fs.readdirSync('/path/to/file').forEach(file => {

    const path = '/path/to/file' + file;
    const data = fs.readFileSync(path);
    const txt = JSON.parse(data);

    console.log(JSON.stringify(txt)); //Displays content of each file

   /* I need the logic to build the lable and sample for the output json */


  });
}

Any help/ guidance is appreciated.

2 Answers 2

1

You can simply use Array.reduce() to create a map:

let animal =  [ { "label": "Dinosaur", "sample": ["#Noun Rex","saurus"] }, { "label": "Lion", "sample": ["simba"] }, { "label": "Tiger", "sample": ["big cat"] } ];
let noun = [ { "label": "Animal", "sample": ["Herbivore","Carnivore"] } ];
let pos =[ { "label": "Noun", "sample": ["Proper","Common"] } ];
    
function getResult(arr, isA, result){
  result = arr.reduce((a, curr)=>{
    a.label = a.label || {};
    a.label[curr.label] = {
      "isA" : isA
    };
    a.sample = a.sample || {};
    a.sample[curr.sample.join("|")] = curr.label;
    return a;
  }, result);
  return result;
}
let result=  {};
getResult(animal, "Animal", result);
getResult(noun, "Noun", result);
getResult(pos, "Pos", result);
console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

1

In addition to your existing code, I've added the logic to construct the desired output.

function buildJSON() {
    // empty result
    let result = { label: {}, sample: {}};

    fs.readdirSync('/path/to/file/').forEach(file => {
        const file_path = '/path/to/file/' + file;
        const data = fs.readFileSync(file_path);
        const items = JSON.parse(data);

        // remove .json extension, this will be used to construct labels
        const file_name = file.replace(/\..+$/, "");

        // loop through each item in the json file
        for(let item of items) {
            // construct labels
            result.label[item.label] = { isA : file_name }

            // construct samples
            result.sample[item.sample.join("|")] = item.label;
        }
    });

    return result;
}

3 Comments

Thank you! This works. Instead of (|) piping is it possible to list them as seperate line items? sample: { '#Noun rex|saurus': 'Dinosaur', 'simba': 'Lion' 'big cat': 'Tiger', 'Herbivore' : 'Animal', 'Carnivore' : 'Animal', 'ProperCommon' : 'Noun', 'Common' : 'Noun' }
Is that doable? Did you get a chance to look at it?
The code is already working close to 80% of what you need, It would be a good exercise for you to make further changes and make it 100%

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.