How to iterate over a JSONObject?

JavaJson

Java Problem Overview


I use a JSON library called JSONObject (I don't mind switching if I need to).

I know how to iterate over JSONArrays, but when I parse JSON data from Facebook I don't get an array, only a JSONObject, but I need to be able to access an item via its index, such as JSONObject[0] to get the first one, and I can't figure out how to do it.

{
   "http://http://url.com/": {
      "id": "http://http://url.com//"
   },
   "http://url2.co/": {
      "id": "http://url2.com//",
      "shares": 16
   }
   ,
   "http://url3.com/": {
      "id": "http://url3.com//",
      "shares": 16
   }
}

Java Solutions


Solution 1 - Java

Maybe this will help:

JSONObject jsonObject = new JSONObject(contents.trim());
Iterator<String> keys = jsonObject.keys();
        
while(keys.hasNext()) {
    String key = keys.next();
    if (jsonObject.get(key) instanceof JSONObject) {
          // do something with jsonObject here      
    }
}

Solution 2 - Java

for my case i found iterating the names() works well

for(int i = 0; i<jobject.names().length(); i++){
    Log.v(TAG, "key = " + jobject.names().getString(i) + " value = " + jobject.get(jobject.names().getString(i)));
}

Solution 3 - Java

I will avoid iterator as they can add/remove object during iteration, also for clean code use for loop. it will be simply clean & fewer lines.

Using Java 8 and Lamda [Update 4/2/2019]

import org.json.JSONObject;

public static void printJsonObject(JSONObject jsonObj) {
    jsonObj.keySet().forEach(keyStr ->
    {
        Object keyvalue = jsonObj.get(keyStr);
        System.out.println("key: "+ keyStr + " value: " + keyvalue);

        //for nested objects iteration if required
        //if (keyvalue instanceof JSONObject)
        //    printJsonObject((JSONObject)keyvalue);
    });
}

Using old way [Update 4/2/2019]

import org.json.JSONObject;

public static void printJsonObject(JSONObject jsonObj) {
    for (String keyStr : jsonObj.keySet()) {
        Object keyvalue = jsonObj.get(keyStr);

        //Print key and value
        System.out.println("key: "+ keyStr + " value: " + keyvalue);

        //for nested objects iteration if required
        //if (keyvalue instanceof JSONObject)
        //    printJsonObject((JSONObject)keyvalue);
    }
}

Original Answer

import org.json.simple.JSONObject;
public static void printJsonObject(JSONObject jsonObj) {
	for (Object key : jsonObj.keySet()) {
		//based on you key types
		String keyStr = (String)key;
		Object keyvalue = jsonObj.get(keyStr);
		
        //Print key and value
        System.out.println("key: "+ keyStr + " value: " + keyvalue);
		
        //for nested objects iteration if required
		if (keyvalue instanceof JSONObject)
			printJsonObject((JSONObject)keyvalue);
	}
}

Solution 4 - Java

Can't believe that there is no more simple and secured solution instead of using an iterator in this answers...

JSONObject names () method returns a JSONArray of the JSONObject keys, so you can simply walk though it in loop:

JSONObject object = new JSONObject ();
JSONArray keys = object.names ();

for (int i = 0; i < keys.length (); i++) {
   
   String key = keys.getString (i); // Here's your key
   String value = object.getString (key); // Here's your value
   
}

Solution 5 - Java

Iterator<JSONObject> iterator = jsonObject.values().iterator();

while (iterator.hasNext()) {
 jsonChildObject = iterator.next();

 // Do whatever you want with jsonChildObject 

  String id = (String) jsonChildObject.get("id");
}

Solution 6 - Java

org.json.JSONObject now has a keySet() method which returns a Set<String> and can easily be looped through with a for-each.

for(String key : jsonObject.keySet())

Solution 7 - Java

Most of the answers here are for flat JSON structures, in case you have a JSON which might have nested JSONArrays or Nested JSONObjects, the real complexity arises. The following code snippet takes care of such a business requirement. It takes a hash map, and hierarchical JSON with both nested JSONArrays and JSONObjects and updates the JSON with the data in the hash map

public void updateData(JSONObject fullResponse, HashMap<String, String> mapToUpdate) {

	fullResponse.keySet().forEach(keyStr -> {
		Object keyvalue = fullResponse.get(keyStr);

		if (keyvalue instanceof JSONArray) {
			updateData(((JSONArray) keyvalue).getJSONObject(0), mapToUpdate);
		} else if (keyvalue instanceof JSONObject) {
			updateData((JSONObject) keyvalue, mapToUpdate);
		} else {
			// System.out.println("key: " + keyStr + " value: " + keyvalue);
			if (mapToUpdate.containsKey(keyStr)) {
				fullResponse.put(keyStr, mapToUpdate.get(keyStr));
			}
		}
	});

}

You have to notice here that the return type of this is void, but sice objects are passed as refernce this change is refelected to the caller.

Solution 8 - Java

First put this somewhere:

private <T> Iterable<T> iteratorToIterable(final Iterator<T> iterator) {
    return new Iterable<T>() {
        @Override
        public Iterator<T> iterator() {
            return iterator;
        }
    };
}

Or if you have access to Java8, just this:

private <T> Iterable<T> iteratorToIterable(Iterator<T> iterator) {
    return () -> iterator;
}

Then simply iterate over the object's keys and values:

for (String key : iteratorToIterable(object.keys())) {
    JSONObject entry = object.getJSONObject(key);
    // ...

Solution 9 - Java

I made a small recursive function that goes through the entire json object and saves the key path and its value.

// My stored keys and values from the json object
HashMap<String,String> myKeyValues = new HashMap<String,String>();

// Used for constructing the path to the key in the json object
Stack<String> key_path = new Stack<String>();

// Recursive function that goes through a json object and stores 
// its key and values in the hashmap 
private void loadJson(JSONObject json){
	Iterator<?> json_keys = json.keys();

    while( json_keys.hasNext() ){
        String json_key = (String)json_keys.next();
        
        try{
        	key_path.push(json_key);
        	loadJson(json.getJSONObject(json_key));
       }catch (JSONException e){
    	   // Build the path to the key
           String key = "";
    	   for(String sub_key: key_path){
    		   key += sub_key+".";
    	   }
    	   key = key.substring(0,key.length()-1);
    	   
    	   System.out.println(key+": "+json.getString(json_key));
    	   key_path.pop();
     	   myKeyValues.put(key, json.getString(json_key));
     	}
    }
  	if(key_path.size() > 0){
  		key_path.pop();
    }
}

Solution 10 - Java

With Java 8 and lambda, cleaner:

JSONObject jObject = new JSONObject(contents.trim());

jObject.keys().forEachRemaining(k ->
{

});

https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#forEachRemaining-java.util.function.Consumer-

Solution 11 - Java

We used below set of code to iterate over JSONObject fields

Iterator iterator = jsonObject.entrySet().iterator();

while (iterator.hasNext())  {
   		Entry<String, JsonElement> entry = (Entry<String, JsonElement>) iterator.next();
    	processedJsonObject.add(entry.getKey(), entry.getValue());
}

Solution 12 - Java

I once had a json that had ids that needed to be incremented by one since they were 0-indexed and that was breaking Mysql auto-increment.

So for each object I wrote this code - might be helpful to someone:

public static void  incrementValue(JSONObject obj, List<String> keysToIncrementValue) {
        Set<String> keys = obj.keySet();
        for (String key : keys) {
            Object ob = obj.get(key);

            if (keysToIncrementValue.contains(key)) {
                obj.put(key, (Integer)obj.get(key) + 1);
            }

            if (ob instanceof JSONObject) {
                incrementValue((JSONObject) ob, keysToIncrementValue);
            }
            else if (ob instanceof JSONArray) {
                JSONArray arr = (JSONArray) ob;
                for (int i=0; i < arr.length(); i++) {
                    Object arrObj = arr.get(0);
                    if (arrObj instanceof JSONObject) {
                        incrementValue((JSONObject) arrObj, keysToIncrementValue);
                    }
                }
            }
        }
    }

usage:

JSONObject object = ....
incrementValue(object, Arrays.asList("id", "product_id", "category_id", "customer_id"));

this can be transformed to work for JSONArray as parent object too

Solution 13 - Java

I made my small method to log JsonObject fields, and get some stings. See if it can be usefull.

object JsonParser {

val TAG = "JsonParser"
 /**
 * parse json object
 * @param objJson
 * @return  Map<String, String>
 * @throws JSONException
 */
@Throws(JSONException::class)
fun parseJson(objJson: Any?): Map<String, String> {
    val map = HashMap<String, String>()

    // If obj is a json array
    if (objJson is JSONArray) {
        for (i in 0 until objJson.length()) {
            parseJson(objJson[i])
        }
    } else if (objJson is JSONObject) {
        val it: Iterator<*> = objJson.keys()
        while (it.hasNext()) {
            val key = it.next().toString()
            // If you get an array
            when (val jobject = objJson[key]) {
                is JSONArray -> {
                    Log.e(TAG, " JSONArray: $jobject")
                    parseJson(jobject)
                }
                is JSONObject -> {
                    Log.e(TAG, " JSONObject: $jobject")
                    parseJson(jobject)
                }
                else -> {
                    Log.e(TAG, " adding to map: $key $jobject")
                    map[key] = jobject.toString()
                }
            }
        }
    }
    return map
}
}

Solution 14 - Java

Below code worked fine for me. Please help me if tuning can be done. This gets all the keys even from the nested JSON objects.

public static void main(String args[]) {
	String s = ""; // Sample JSON to be parsed

	JSONParser parser = new JSONParser();
	JSONObject obj = null;
	try {
		obj = (JSONObject) parser.parse(s);
		@SuppressWarnings("unchecked")
		List<String> parameterKeys = new ArrayList<String>(obj.keySet());
		List<String>  result = null;
		List<String> keys = new ArrayList<>();
		for (String str : parameterKeys) {
			keys.add(str);
			result = this.addNestedKeys(obj, keys, str);
		}
		System.out.println(result.toString());
	} catch (ParseException e) {
		e.printStackTrace();
	}
}
public static List<String> addNestedKeys(JSONObject obj, List<String> keys, String key) {
	if (isNestedJsonAnArray(obj.get(key))) {
		JSONArray array = (JSONArray) obj.get(key);
		for (int i = 0; i < array.length(); i++) {
			try {
				JSONObject arrayObj = (JSONObject) array.get(i);
				List<String> list = new ArrayList<>(arrayObj.keySet());
				for (String s : list) {
					putNestedKeysToList(keys, key, s);
					addNestedKeys(arrayObj, keys, s);
				}
			} catch (JSONException e) {
				LOG.error("", e);
			}
		}
	} else if (isNestedJsonAnObject(obj.get(key))) {
		JSONObject arrayObj = (JSONObject) obj.get(key);
		List<String> nestedKeys = new ArrayList<>(arrayObj.keySet());
		for (String s : nestedKeys) {
			putNestedKeysToList(keys, key, s);
			addNestedKeys(arrayObj, keys, s);
		}
	}
	return keys;
}

private static void putNestedKeysToList(List<String> keys, String key, String s) {
	if (!keys.contains(key + Constants.JSON_KEY_SPLITTER + s)) {
		keys.add(key + Constants.JSON_KEY_SPLITTER + s);
	}
}



private static boolean isNestedJsonAnObject(Object object) {
	boolean bool = false;
	if (object instanceof JSONObject) {
		bool = true;
	}
	return bool;
}

private static boolean isNestedJsonAnArray(Object object) {
	boolean bool = false;
	if (object instanceof JSONArray) {
		bool = true;
	}
	return bool;
}

Solution 15 - Java

This is is another working solution to the problem:

public void test (){

	Map<String, String> keyValueStore = new HasMap<>();
	Stack<String> keyPath = new Stack();
	JSONObject json = new JSONObject("thisYourJsonObject");
	keyValueStore = getAllXpathAndValueFromJsonObject(json, keyValueStore, keyPath);
	for(Map.Entry<String, String> map : keyValueStore.entrySet()) {
		System.out.println(map.getKey() + ":" + map.getValue());
	}	
}

public Map<String, String> getAllXpathAndValueFromJsonObject(JSONObject json, Map<String, String> keyValueStore, Stack<String> keyPath) {
	Set<String> jsonKeys = json.keySet();
	for (Object keyO : jsonKeys) {
		String key = (String) keyO;
		keyPath.push(key);
		Object object = json.get(key);

		if (object instanceof JSONObject) {
			getAllXpathAndValueFromJsonObject((JSONObject) object, keyValueStore, keyPath);
		}

		if (object instanceof JSONArray) {
			doJsonArray((JSONArray) object, keyPath, keyValueStore, json, key);
		}

		if (object instanceof String || object instanceof Boolean || object.equals(null)) {
			String keyStr = "";

			for (String keySub : keyPath) {
				keyStr += keySub + ".";
			}

			keyStr = keyStr.substring(0, keyStr.length() - 1);

			keyPath.pop();

			keyValueStore.put(keyStr, json.get(key).toString());
		}
	}

	if (keyPath.size() > 0) {
		keyPath.pop();
	}

	return keyValueStore;
}

public void doJsonArray(JSONArray object, Stack<String> keyPath, Map<String, String> keyValueStore, JSONObject json,
		String key) {
	JSONArray arr = (JSONArray) object;
	for (int i = 0; i < arr.length(); i++) {
		keyPath.push(Integer.toString(i));
		Object obj = arr.get(i);
		if (obj instanceof JSONObject) {
			getAllXpathAndValueFromJsonObject((JSONObject) obj, keyValueStore, keyPath);
		}

		if (obj instanceof JSONArray) {
			doJsonArray((JSONArray) obj, keyPath, keyValueStore, json, key);
		}

		if (obj instanceof String || obj instanceof Boolean || obj.equals(null)) {
			String keyStr = "";

			for (String keySub : keyPath) {
				keyStr += keySub + ".";
			}

			keyStr = keyStr.substring(0, keyStr.length() - 1);

			keyPath.pop();

			keyValueStore.put(keyStr , json.get(key).toString());
		}
	}
	if (keyPath.size() > 0) {
		keyPath.pop();
	}
}

Solution 16 - Java

The simpler approach is (just found on W3Schools):

let data = {.....}; // JSON Object
for(let d in data){
    console.log(d); // It gives you property name
    console.log(data[d]); // And this gives you its value
}

UPDATE

This approach works fine until you deal with the nested object so this approach will work.

const iterateJSON = (jsonObject, output = {}) => {
  for (let d in jsonObject) {
    if (typeof jsonObject[d] === "string") {
      output[d] = jsonObject[d];
    }
    if (typeof jsonObject[d] === "object") {
      output[d] = iterateJSON(jsonObject[d]);
    }
  }
  return output;
}

And use the method like this

let output = iterateJSON(your_json_object);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEric HjalmarssonView Question on Stackoverflow
Solution 1 - JavaRickeyView Answer on Stackoverflow
Solution 2 - JavaAssemblyXView Answer on Stackoverflow
Solution 3 - JavamaazView Answer on Stackoverflow
Solution 4 - JavaAcunaView Answer on Stackoverflow
Solution 5 - JavaaviomaksimView Answer on Stackoverflow
Solution 6 - JavaBurritoView Answer on Stackoverflow
Solution 7 - JavaShekharView Answer on Stackoverflow
Solution 8 - JavaEbrahim ByagowiView Answer on Stackoverflow
Solution 9 - JavaSkullboxView Answer on Stackoverflow
Solution 10 - JavaThomas DecauxView Answer on Stackoverflow
Solution 11 - JavaSanchi GirotraView Answer on Stackoverflow
Solution 12 - JavaMichail MichailidisView Answer on Stackoverflow
Solution 13 - JavaAnton KoganView Answer on Stackoverflow
Solution 14 - JavaRamjiView Answer on Stackoverflow
Solution 15 - JavaHuy Thành TrươngView Answer on Stackoverflow
Solution 16 - JavaUsama MajidView Answer on Stackoverflow