3

So I have a JSON File with multiple arrays. "data" contains a whole bunch of words that contain "clues" to each word. I've parsed up a JSON file with one array but I'm unsure of how to parse this up. I know that JSONObjects are surrounded by {} and JSONArrays are surrounded by [], so "data" should be a JSONObject and each word an array.

{
  "data":{
     "abase":[
       "put down",
       "humiliate",
       "cut down",
     ],
     "abate":[
       "diminish",
       "let up",
     ],
     "abbot":[
      "monastery head",
      "monastic title",
     ]
 }
}

I can parse up a JSON file with a singular array and create objects from the data as such:

JSONObject allThings = loadJSONObject("filename.json");
JSONArray arr = getJSONArray("titleofarray");
for (int x = 0; x<=arr.size(); x++){
    String fieldOne = arr.getJSONObject(x).getString("firstField");
    int fieldTwo = arr.getJSONObject(x).getInt("secondField");
}

Can I create an ArrayList of JSONArrays and add each array in the file to that ArrayList with a for-each? Sorry if I'm not 100% clear on my question, it's hard to phrase a question about something you don't understand, but if you need clarification, please let me know, I'd be glad to explain in further detail.

Edit: I'm using Processing/Java

2
  • 1
    Why do you want to parse the JSON file manually? Can't you just use a library for parsing JSONs like GSON or Jackson? Commented Nov 25, 2016 at 19:06
  • Well, I'm learning data structures and interacting with files, so I'm trying to get a good understanding of JSON at this point. Commented Nov 25, 2016 at 19:12

2 Answers 2

4

In addition to Kevin's answer, you can iterate over the JSONObject's keys():

  JSONObject associative = loadJSONObject("associative.json");
  JSONObject associativeData = associative.getJSONObject("data"); 

  ArrayList<JSONArray> listA = new ArrayList<JSONArray>(); 

  for(Object key : associativeData.keys()){
    String keyName = (String)key;
    JSONArray data = associativeData.getJSONArray(keyName);
    println(keyName,"=",data);
    listA.add(data);
  }

  System.err.println(listA);

associative.json:

{
  "data":{
     "abase":[
       "put down",
       "humiliate",
       "cut down"
     ],
     "abate":[
       "diminish",
       "let up"
     ],
     "abbot":[
      "monastery head",
      "monastic title"
     ]
 }

}

You could also re-organize your JSON data so it fits your goal. Currently you have words and synonyms in a JSON object (associative array). You could easily convert that to a JSON array and structure the data so it's easy to access/parse. For example: array.json

{
  "data":[
     {
      "word":"abase",
      "synonyms":[
         "put down",
         "humiliate",
         "cut down"
         ]
      },
      {
        "word":"abate",
        "synonyms":[
           "diminish",
           "let up"
        ]
     },
     {
        "word":"abbot",
        "synonyms":[
          "monastery head",
          "monastic title"
        ]
      }
  ]
 }

You can still make an ArrayList if you want to, but you shouldn't really need it, you can easily access each word and synonyms directly. It should be simpler not having to convert/parse and just access what you need:

ArrayList<JSONArray> listB = new ArrayList<JSONArray>(); 

  JSONObject array = loadJSONObject("array.json");
  JSONArray arrayData = array.getJSONArray("data");
  for(int i = 0 ; i < arrayData.size(); i++){
    JSONObject data = arrayData.getJSONObject(i);
    println("\t",data.getString("word"),"=",data.getJSONArray("synonyms"));

    listB.add(data.getJSONArray("synonyms"));
  }

  System.err.println(listB);

Update here's an example that renders the text on screen:

import processing.data.*;

void setup(){
  size(400,400);
  background(0);

  int textX = 10;
  int textY = 20;

  JSONObject array = loadJSONObject("array.json");
  JSONArray arrayData = array.getJSONArray("data");
  for(int i = 0 ; i < arrayData.size(); i++){
    JSONObject data = arrayData.getJSONObject(i);
    String word = data.getString("word");
    JSONArray synonyms = data.getJSONArray("synonyms");
    println(word,"=",synonyms);

    //render on screen
    text(word.toUpperCase(),textX,textY);
    for(int j = 0 ; j < synonyms.size(); j++){
      String synonym = synonyms.getString(j);
      text(synonym,textX,textY + (textY * (j+1)));
    }

    //increment x position for next word
    textX += 100;
  }

}

json text parse and preview

Update 2 Here's an encapsulation example that uses a proof of concept hint display when hovering over a word:

import processing.data.*;

ArrayList<Word> words = new ArrayList<Word>(); 

void setup(){
  size(400,400);

  int textX = 10;
  int textY = 20;

  JSONObject array = loadJSONObject("array.json");
  JSONArray arrayData = array.getJSONArray("data");
  for(int i = 0 ; i < arrayData.size(); i++){
    JSONObject data = arrayData.getJSONObject(i);
    String word = data.getString("word");
    JSONArray synonyms = data.getJSONArray("synonyms");
    println(word,"=",synonyms);

    words.add(new Word(textX,textY,"hint #"+(i+1),data));

    //increment x position for next word
    textX += 100;
  }

}

void draw(){
  background(0);
  for(Word word : words){
    word.draw();
  }
}

class Word{
  String hint = "...";
  JSONObject data;

  float x,y;
  float textWidth;
  float textHeight = 20;



  Word(float x,float y,String hint,JSONObject data){
    this.x = x;
    this.y = y;
    this.hint = hint;
    this.data = data;
    textWidth = textWidth(data.getString("word"));
  }

  void draw(){
    fill(255);
    String word = data.getString("word");
    JSONArray synonyms = data.getJSONArray("synonyms");
    text(word.toUpperCase(),x,y);
    for(int j = 0 ; j < synonyms.size(); j++){
      String synonym = synonyms.getString(j);
      text(synonym,x,y + (textHeight * (j+1)));
    }
    fill(0,192,0);
    //hint tooltip
    //if mouse within word bounding box
    if((mouseX >= x && mouseX <= x + textWidth) &&
       (mouseY >= y-textHeight && mouseY <= y)){
         //render the text at mouse coordinates
         //be aware that y is the base of the text -> be sure to check out the reference for text functions (e.g. textAscent(),textDescent(),etc.)
      text(hint,mouseX,mouseY+textHeight);  
    }


  }


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

6 Comments

Thanks for your response George. I see in Kevin's example, I would need to enter every single word in that JSON file as it's own seperate JSONArray object. In your example on the other hand, you loop through all of the "keys" in "associativeData," then pass the name of the key into a String, then pass that into a getJSONArray()? Once I get there it's just like the example I used in my post?
The first example above uses JSON data formatted pretty much as you had in your question/post. The only difference is I'm pointing you to the keys() object that will allow you to loop through the data instead of manually using each word. What your question doesn't explain is how you plan to use the data in the end. Perhaps there's a simpler way to structure and access it ?
I plan to put all the words with their hints into a Word object, which contains the word itself, as well as an ArrayList containing the hints to the word. The constructor would be as such: 'public Word(String name, ArrayList<String>hints). I should be able to get the needed data, correct?
Correct. I had a hunch this would be case, therefore I recommend have a play with the second example I shared. You might be able to use the data directly without needing a Word class an array list of strings...have a look at the updated example
No worries. You can use composition to write a Word class that stores a JSONObject (with the word and synonyms) + all the other data (hints/rendering/etc.). If the answer was helpful feel free to vote up and mark ;)
|
1

Break your problem down into smaller steps.

Step 1: Can you get to the data object inside the JSON?

You can do this by calling the loadJSONObject() function to load all of the JSON, then calling getJSONObject() to get to the data object:

JSONObject json = loadJSONObject("data.json"); JSONObject data = json.getJSONObject("data"); println(data);

Step 2: Can you get to the three fields inside the data object?

I don't think there's a standard, out-of-the-box way to loop over each of the fields using Processing's JSONObject. So you'll have to get them manually:

JSONObject json = loadJSONObject("data.json");
JSONObject data = json.getJSONObject("data");
JSONArray abase = data.getJSONArray("abase");
JSONArray abate = data.getJSONArray("abate");
JSONArray abbot = data.getJSONArray("abbot");
println(abase);
println(abate);
println(abbot);

Step 3: Now that you have the JSONArray instances, what do you want to do with them?

Once you have the JSONArray instances, you can do whatever you want with them, including looping over each of them and adding their contents to a single ArrayList.

If you want to write code that loops over the fields themselves, then you'll have to write that yourself. Googling "Java get json object field names" returns a ton of results.

Comments

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.