3

I have a JSON array like this:

[{
  "name": "com",
  "children": [
    {
      "name": "project",
      "children": [
        {
          "name": "server"
        },
        {
          "name": "client",
          "children": [
            {
              "name": "util"
            }
          ]
        }
      ]
    }
  ]
}]

And I need all the names from all the JSON objects. Is there any way to get this done in java?

I want a recursive function.

My expected result is like :

[
    {name:"com"},
    {"name":"project"},
    {"name":"server"},
    {"name":"client"},
    {"name":"util"}]
Vüsal
  • 2,580
  • 1
  • 12
  • 31
Pushpak
  • 77
  • 10
  • 8
    What have you tried so far? Why didn't it work? – BackSlash Feb 11 '19 at 10:43
  • JSONArray ja= new JSONArray(myarray); JSONObject jo= ja.getJSONObject(0); System.out.println(jo.getString("name")); Actually i am trying like that so its type of workaround i want a function that reads nested arrays inside array – Pushpak Feb 11 '19 at 10:45
  • and my data is dynamic so i dont know how many json objects are getting added inside the children array thats why i want a generic function that reduce my efforts – Pushpak Feb 11 '19 at 10:46
  • you were a bit quick deleting that other question. have a look at https://stackoverflow.com/questions/4216745/java-string-to-date-conversion ... what I would do: simply use String.substring() to fetch the first X chars of each line. X would be the number you know that your timestamps need. Then try to parse that string as date. if it works good, if not, you got something else on that line. – GhostCat May 30 '19 at 18:18
  • But please understand: that is really basic stuff, and you shouldnt come here and **only** show requirements "here is what I need", together with **zero** efforts of you solving the problem yourself. Please understand: we **help you solving problems** we do not solve them **for** you. finally: be careful: you already have some questions with negative scores, if you continue like that, you might get banned from asking questions. So, please: dont come here and expect people to show you super basic things. Stuff that was asked answered here many many times before. – GhostCat May 30 '19 at 18:20

3 Answers3

2

This is a simple recursive function to get all names properties from your json array:

public static Collection<String> getAllNames(JSONArray jsonArray, List<String> names) {
    for (int i = 0; i < jsonArray.length(); i++) {
        JSONObject object = jsonArray.getJSONObject(i);
        names.add(object.getString("name"));
        if (object.has("children")) {
            JSONArray children = object.getJSONArray("children");
            getAllNames(children, names);
        }
    }

    return names;
}

This will provide you a list of names that you can use to construct a new json array. A possible way is this:

 public static JSONArray getJsonArraysOfNames(List<String> names) {
    JSONArray jsonArray = new JSONArray();
    for (String name : names) {
        JSONObject object = new JSONObject();
        object.put("name", name);
        jsonArray.put(object);
    }

    return jsonArray;
}

UPDATE

If you prefer an all-in-one solution then you can go with this approach:

public static JSONArray getNames(JSONArray inputArray, JSONArray outputArray) {
    for (int i = 0; i < inputArray.length(); i++) {
        JSONObject inputObject = inputArray.getJSONObject(i);

        JSONObject outputObject = new JSONObject();
        outputObject.put("name", inputObject.getString("name"));
        outputArray.put(outputObject);

        if (inputObject.has("children")) {
            JSONArray children = inputObject.getJSONArray("children");
            getNames(children, outputArray);
        }
    }

    return outputArray;
}
noiaverbale
  • 1,550
  • 13
  • 27
2

Wrote a little program to solve your problem.

A recursive Type Entity that has 2 attributes, "name" of type String and "children" of Type List. Since this is the structure of your peaceable JSON. The JSON then can be easily parsed using Jackson API in one line

List<Entity> clas = mapper.readValue(json,
                mapper.getTypeFactory().constructCollectionType(List.class, Entity.class));

After successfully creating the object, all we need to do is traverse it recursively through the hierarchy and in every step return the name attribute with some extra text that gives the result a valid JSON form. Code below.

Main.java

import java.io.IOException;
import java.util.List;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

public class Main {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {

    String json = "[{\"name\":\"com\",\"children\":[{\"name\":\"project\",\"children\":[{\"name\":\"server\"},{\"name\":\"client\",\"children\":[{\"name\":\"util\"}]}]}]}]";

    ObjectMapper mapper = new ObjectMapper();
    List<Entity> clas = mapper.readValue(json,
            mapper.getTypeFactory().constructCollectionType(List.class, Entity.class));

    String names = getChildren(clas);
    String result = "[" + names.substring(0, names.length() - 1) + "]";

    System.out.println(result);
}

private static String getChildren(List<Entity> clas) {
    String names = "";
    for (Entity class1 : clas) {
        if (class1.getChildren() == null) {
            names += "{name : \"" + class1.getName() + "\"},";
            if (clas.indexOf(class1) == (clas.size() - 1)) {
                return names;
            }
            continue;
        }
        names += "{name : \"" + class1.getName() + "\"},";

        names += getChildren(class1.getChildren());
    }
    return names;
}
}

Entity.java

import java.util.List;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public  class Entity {

    String name;
    List<Entity> children;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Entity> getChildren() {
        return children;
    }

    public void setChildren(List<Entity> children) {
        this.children = children;
    }}
Sibgha
  • 479
  • 3
  • 10
1

Just try to trigger the "[" and "]". Pass recursively a string that can add the cutted utile parts of the json to the new format. At end you can return this string to the original call.. when the recursive ends.

I was writting an example for you specific case but in C#, and it seems to eb easier without recursivity.

   public string GetNames(string originalJson)
        {
            string namesString = "[";
            bool newItem = false;

            for(int i = 0; i < originalJson.Length; i++ )
            {                
                if(newItem)
                {
                    if (originalJson[i] == ',')
                    {
                        newItem = false;
                        namesString += "}";
                    }

                    else
                        namesString += originalJson[i];

                }
                else if (originalJson[i] == '{')
                {
                    newItem = true;
                    namesString += "{";
                }


            }
            namesString = namesString.Substring(0, namesString.Length - 1);
            namesString += "]";
            return namesString;
        }

I am not sure if this is what you are looking for.

Mr.Deer
  • 476
  • 6
  • 17