JSONObject üzerinden yineleme nasıl yapılır?


312

Ben denilen bir JSON kütüphane kullanın JSONObject(gerekiyorsa geçiş umursamıyorum).

Nasıl yineleyeceğini biliyorum JSONArrays, ama Facebook'tan JSON verilerini ayrıştırdığımda bir dizi almıyorum, sadece bir JSONObject, ama JSONObject[0]ilkini almak gibi dizinine bir öğeye erişebilmeliyim ve ben nasıl yapılacağını anlayamıyorum.

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


Yanıtlar:


594

Belki bu yardımcı olur:

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
Herkese dikkat et, jObject.keys () yineleyiciyi ters dizin düzeniyle döndürür.
macio.Jun

77
@ macio.Jun Yine de, düzen haritalarda önemli değil: anahtarlar JSONObjectsıralanmamış ve iddianız özel bir uygulamanın basit bir yansımasıydı;)
caligari

6
Tüm anahtarlara sırayla ihtiyaç duyduğumuzda ne kullanılır?
düşkün

11
Hafif tartışma: Bu, anahtar aramayı iki kez yapmaya yol açmıyor mu? Belki 'Object o = jObject.get (key)' yapmak daha iyi, daha sonra türünü kontrol edin ve sonra tekrar get (key) çağırmak zorunda kalmadan kullanın.
Tom

1
@Tom For-Her döngüler bir koleksiyon üzerinde yineleme yaparken faydalıdır:for (String key : keys)
caligari

86

benim durumum için names()iyi çalışır yineleme bulundu

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
Bu örnek IteratingJava'da olduğu gibi gerçekten anlaşılmasa da , oldukça iyi çalışıyor! Teşekkürler.
Tim Visée

57

Döngü için temiz kod kullanımı için, yineleme sırasında nesne ekleyebilir / kaldırabilir gibi yineleyiciden kaçınacağım. sadece temiz ve daha az satır olacak.

Java 8 ve Lamda'yı kullanma [Güncelleme 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);
    });
}

Eski yöntemi kullanma [Güncelleme 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);
    }
}

Orijinal Yanıt

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
Hiçbir zaman org.json.simple (bir google kütüphanesi) kullandıklarını söylemediler. Standart org.json.JSONObject, maalesef bir yineleyici kullanmaya zorlar.
Amalgovinus

1
Sen kurtardın ama buraya!
Lukuluba

1
org.json.JSONObject'te keySet () yoktur
Ridhuvarshan


38

Bu cevaplarda yineleyici kullanmaktan daha basit ve güvenli bir çözüm olmadığına inanamıyorum ...

JSONObject names ()yöntemi anahtarlardan JSONArraybirini döndürür JSONObject, böylece döngüde olsa da yürüyebilirsiniz:

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
burada nesne nedir?
RCS

1
Öyle JSONObject. Gibi bir şey JSONObject object = new JSONObject ("{\"key1\",\"value1\"}");. Ama buna ham json koymayın ile onun içinde öğeler eklemek put ()yöntemle: object.put ("key1", "value1");.
Acuna

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();Muhtemelen tanımlamak gerekir jsonChildObjectgibi JSONObject jsonChildObject = iterator.next();hayır?
kontur

1
Bu çözümü seviyorum, ama ilan Iterator<JSONObject>etmek bir uyarı verecektir. Ben jenerik ile değiştirmek <?>ve çağrı üzerine bir döküm yapmak next(). Ayrıca, bir oyuncu kadrosu yapmak getString("id")yerine get("id")kaydetmek istiyorum .
RTF

9

org.json.JSONObject artık a döndüren Set<String>ve her biri için kolayca geçiş yapabilen bir keySet () yöntemine sahiptir .

for(String key : jsonObject.keySet())

Bence bu en uygun çözüm. Tavsiye için teşekkürler :)
Yurii Rabeshko

1
Örneğinizi tamamlayabilir misiniz?
uçurum

6

Önce bunu bir yere koyun:

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

Veya Java8'e erişiminiz varsa, sadece bu:

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

Ardından nesnenin anahtarları ve değerleri üzerinde tekrarlayın:

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

Buna oy verdim, ancak "String key: ...." derlenmiyor ve yineleyicide kontrol edilmemiş bir döküm uyarısından kaçınmanın bir yolu yok gibi görünüyor. Aptal yineleyiciler.
Amalgovinus

2

Tüm json nesnesinin içinden geçen ve anahtar yolunu ve değerini kaydeden küçük bir özyinelemeli işlev yaptım.

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

JSONObjectAlanları yinelemek için aşağıdaki kod kümesini kullandık

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

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

1

Bir zamanlar 0-endeksli ve Mysql otomatik artış kırma beri bir tarafından artırılması gereken kimlikleri olan bir json vardı.

Yani her nesne için bu kodu yazdım - birisi için yararlı olabilir:

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

kullanımı:

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

bu da JSONArray için üst nesne olarak çalışacak şekilde dönüştürülebilir


1

Buradaki cevapların çoğu düz JSON yapıları içindir, iç içe JSONArrays veya İç içe JSONObjects olabilecek bir JSON varsa, gerçek karmaşıklık ortaya çıkar. Aşağıdaki kod snippet'i böyle bir iş gereksinimini karşılar. Karma bir harita ve hem iç içe geçmiş JSONArrays hem de JSONObjects içeren hiyerarşik JSON alır ve karma haritasındaki verilerle JSON'u günceller

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

}

Burada bunun dönüş türünün geçersiz olduğunu fark etmelisiniz, ancak sice nesneleri refernce olarak iletildi, bu değişiklik arayan kişiye yeniden seçildi.


0

Aşağıdaki kod benim için iyi çalıştı. Ayarlama yapılabilirse lütfen bana yardım edin. Bu, tüm anahtarları iç içe JSON nesnelerinden bile alır.

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

Bu, soruna başka bir çalışma çözümüdür:

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();
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.