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"}]
5
  • 8
    What have you tried so far? Why didn't it work? Commented Feb 11, 2019 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 Commented Feb 11, 2019 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 Commented Feb 11, 2019 at 10:46
  • you were a bit quick deleting that other question. have a look at stackoverflow.com/questions/4216745/… ... 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. Commented May 30, 2019 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. Commented May 30, 2019 at 18:20

3 Answers 3

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;
}
Sign up to request clarification or add additional context in comments.

Comments

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;
    }}

Comments

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.

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.