JSONObject पर पुनरावृति कैसे करें?


312

मैं JSON लाइब्रेरी नामक का उपयोग करता हूं JSONObject हूं (यदि मुझे आवश्यकता है तो स्विच करने में कोई आपत्ति नहीं है)।

मुझे पता है कि मैं इसे कैसे करना चाहता हूं JSONArrays, लेकिन जब मैं फेसबुक से JSON डेटा पार्स करता हूं, तो मुझे कोई सरणी नहीं मिलती है, केवल एक JSONObject, लेकिन मुझे इसके सूचकांक के माध्यम से किसी आइटम तक पहुंचने में सक्षम होने की आवश्यकता होती है, जैसे JSONObject[0]कि पहले एक, और मैं यह कैसे करना है यह पता नहीं लगा सकते।

{
   "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
   }
}


जवाबों:


594

शायद इससे मदद मिलेगी:

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

20
सभी से सावधान रहें, jObject.keys () रिवर्स इंडेक्स ऑर्डर के साथ पुनरावृत्तिकर्ता को लौटाता है।
macio.Jun

77
@ macio.Jun फिर भी, यह आदेश गुणों के नक्शे में कोई फर्क नहीं पड़ता: चाबियाँ अनियंत्रित JSONObjectहैं और आपका जोर निजी कार्यान्वयन का एक सरल प्रतिबिंब था;)
कैलिगारी

6
जब हमें क्रमिक रूप से सभी कुंजी की आवश्यकता होती है तो क्या उपयोग करें?
उत्सुक

11
थोड़ा विचित्र: यह दो बार कुंजी देखने के लिए नेतृत्व नहीं करता है? हो सकता है कि 'ऑब्जेक्ट ओ = jObject.get (कुंजी)' करने के लिए बेहतर है, फिर उसके प्रकार की जांच करें और फिर उसका उपयोग करें, बिना कॉल किए (कुंजी) फिर से कॉल करें।
टॉम

1
@ टोम फॉर-प्रत्येक लूप उपयोगी होते हैं जब एक संग्रह पर पुनरावृत्ति होती है:for (String key : keys)
कैलिगारी

86

मेरे मामले के लिए मुझे यह names()अच्छी तरह से काम करता पाया गया

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

1
हालांकि यह उदाहरण वास्तव Iteratingमें जावा के रूप में नहीं समझा गया है, यह काफी अच्छी तरह से काम करता है! धन्यवाद।
टिम विसे

57

मैं पुनरावृत्ति से बचूंगा क्योंकि वे पुनरावृत्ति के दौरान ऑब्जेक्ट को जोड़ / हटा सकते हैं, लूप के लिए स्वच्छ कोड उपयोग के लिए भी। यह केवल साफ और कम लाइनों वाला होगा।

जावा 8 और लैमडा का उपयोग करना [अपडेट 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);
    });
}

पुराने तरीके का उपयोग करना [अपडेट 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);
    }
}

मूल उत्तर

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

5
उन्होंने कभी नहीं कहा कि वे org.json.simple (जो एक Google लाइब्रेरी है) का उपयोग कर रहे थे। मानक org.json.JSONObject आपको दुर्भाग्य से उपयोग करने के लिए मजबूर करता है।
अमलगोविनास

1
तुमने मेरा लेकिन यहाँ बचा लिया!
लुकुलुबा

1
org.json.JSONObject के पास keySet () नहीं है
रिधुदर्शन

क्या संस्करण देख रहे हो? stleary.github.io/JSON-java/org/json/JSONObject.html#keySet--
माज़

38

विश्वास नहीं हो सकता है कि इस उत्तर में एक पुनरावृत्त का उपयोग करने से ज्यादा सरल और सुरक्षित समाधान नहीं है ...

JSONObject names ()विधि कुंजियों JSONArrayका एक रिटर्न देती है JSONObject, इसलिए आप बस इसे लूप में चला सकते हैं:

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

}

1
यहाँ क्या वस्तु है?
आरसीएस

1
यह है JSONObject। कुछ इस तरह JSONObject object = new JSONObject ("{\"key1\",\"value1\"}");। लेकिन इसमें कच्चा जूस न डालें, इसमें put ()विधि के साथ आइटम जोड़ें object.put ("key1", "value1");:।
एक्यूना

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

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

 // Do whatever you want with jsonChildObject 

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

jsonChildObject = iterator.next();शायद परिभाषित करना चाहिए jsonChildObject, जैसे JSONObject jsonChildObject = iterator.next();, नहीं?
कांटूर

1
मुझे यह समाधान पसंद है, लेकिन घोषणा करने Iterator<JSONObject>से एक चेतावनी मिलेगी। मैं इसे जेनेरिक से बदलूंगा <?>और कॉल पर एक कास्ट करूंगा next()। इसके अलावा, मैं एक कलाकार को बचाने के getString("id")बजाय उपयोग करूँगा get("id")
RTF

9

org.json.JSONObject के पास अब एक कीसेट () विधि है जो रिटर्न करती है Set<String>और आसानी से प्रत्येक के लिए एक के माध्यम से लूप किया जा सकता है।

for(String key : jsonObject.keySet())

मुझे लगता है कि यह सबसे सुविधाजनक उपाय है। सलाह के लिए धन्यवाद :)
यूरी रबेशको

1
क्या आप अपना उदाहरण पूरा कर सकते हैं?
chasm

6

पहले इसे कहीं रखो:

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

या यदि आपके पास जावा 8 तक पहुंच है, तो बस यह:

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

तो बस वस्तु की कुंजी और मूल्यों पर पुनरावृति:

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

मैंने इसके लिए मतदान किया, लेकिन "स्ट्रिंग कुंजी: ...." संकलन नहीं करता है, और इट्रेटर पर अनियंत्रित कलाकारों की चेतावनी से बचने का कोई तरीका प्रतीत नहीं होता है। मूर्ख पुनरावृत्तियों।
अमलगोविनास

2

मैंने एक छोटा सा पुनरावर्ती कार्य किया जो संपूर्ण जसन ऑब्जेक्ट के माध्यम से जाता है और मुख्य पथ और इसके मूल्य को बचाता है।

// 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();
    }
}

2

जावा 8 और लैम्ब्डा के साथ, क्लीनर:

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-


यह केवल कुंजियों को प्रदर्शित करता है लेकिन आपको अभी भी मूल्य प्राप्त करने की आवश्यकता है, इसलिए आप jObject.get (k) का उपयोग कर सकते हैं;
मिकेल

मुझे "नल से उपभोक्ता तक कास्ट न्यूनतम एपीआई 24 की आवश्यकता है"
हर्षिल पानसरे

2

हमने JSONObjectखेतों पर पुनरावृति करने के लिए कोड के नीचे सेट का उपयोग किया

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

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

1

मेरे पास एक बार एक जसन था जिसमें आईडी थे जिन्हें एक-एक करके बढ़ाना पड़ता था क्योंकि वे 0-अनुक्रमित थे और जो कि मैसिकल-इंक्रीमेंट तोड़ रहा था।

इसलिए प्रत्येक वस्तु के लिए मैंने यह कोड लिखा है - किसी के लिए उपयोगी हो सकता है:

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

उपयोग:

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

यह JSONArray के लिए मूल वस्तु के रूप में भी काम करने के लिए रूपांतरित किया जा सकता है


1

यहां अधिकांश उत्तर फ्लैट JSON संरचनाओं के लिए हैं, यदि आपके पास JSON है जिसमें JSONArrays या Nested JSONObjects हो सकते हैं, तो वास्तविक जटिलता उत्पन्न होती है। निम्नलिखित कोड स्निपेट ऐसी व्यावसायिक आवश्यकता का ध्यान रखता है। यह नेस्टेड JSONArrays और JSONObjects दोनों के साथ एक हैश मैप और पदानुक्रमित JSON लेता है और हैश मैप में डेटा के साथ JSON अपडेट करता है

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 JSONArray) {
            updateData((JSONObject) keyvalue, mapToUpdate);
        } else {
            // System.out.println("key: " + keyStr + " value: " + keyvalue);
            if (mapToUpdate.containsKey(keyStr)) {
                fullResponse.put(keyStr, mapToUpdate.get(keyStr));
            }
        }
    });

}

आपको यहाँ ध्यान देना है कि इस प्रकार का रिटर्न शून्य है, लेकिन इस परिवर्तन को कॉल करने वाले के रूप में संदर्भित करने के लिए साइन्स ऑब्जेक्ट को पास किया जाता है।


0

नीचे दिए गए कोड ने मेरे लिए ठीक काम किया। ट्यूनिंग हो सकती है तो कृपया मेरी मदद करें। यह नेस्टेड JSON ऑब्जेक्ट्स से भी सभी कुंजी प्राप्त करता है।

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

-1

यह समस्या का एक और कारगर उपाय है:

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();
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.