2 JsonArray vergleichen, geht es auch einfacher ?

fireGlurak

Aktives Mitglied
Nabend 🙂

Gegeben sind 2 JsonArray mit einer Menge von Objekten und jedes dieser Objekte besitzt eine Nummer. Nun möchte Array1 mit Array2 hinsichtlich der Nummer vergleichen und bei einem Match möchte ich das Objekt aus Array2 entsprechend erweitern.
Zwar kann ich dies lösen, allerdings sagt mir mein Gefühl, dass dies auch noch einfacher geht. Da ich ähnliche "Probleme" in der Vergangenheit schon mal hatte, dachte ich, dass ich mal nachfrage wie man sowas besser lösen könnte 😀

Vom Bauchgefühl würde ich sagen, dass dies mit Streams "einfach" zu lösen ist, nur leider bin ich damit noch nicht wirlklich vertraut und meine Gehversuche liefen dort leider ins leere. Möglicherweise lässt sich dies aber auch anders Lösen und da wäre ich für Vorschläge sehr dankbar 🙂

Ich habe jetzt mal versucht ein vereinfachtes Beispiel zu konstruieren um mein Ziel verständlicher zu machen. Zugegeben, mein "vereinfachtes" Beispiel scheint mir noch ein wenig zu abstrakt, aber ich hoffe es genügt 🙂

Nachstehender Code besteht im Grunde aus folgenden Schritten
->Iteriere über jArrA
->Ermittle zu jedem Obj. aus jArrA den Index aus jArrB in dem du über jArrB iterierst
(theoretisch kann bei einem Match die Schleife auch beendet werden, das bildet der Code nicht ab, aber darum geht es erstmal nicht)
-> Bearbeite das gefundene Objekt in jArrErgebnis

Im Grunde bräuchte ich auch kein Ergebis Array, sondern besser wäre es wenn ich jArrB direkt überarbeite, aber ich habe das in meinem Beispiel einfach mal mit einem Ergebnis Array gelöst.

Nach Ausführung erhalte ich das korrekte Ergebnis

[{"Nummer":6},{"Nummer":5,"einKey":"123"},{"Nummer":2,"einKey":"123"}]


public class Test { public static void main(String[] args) { JSONArray jArrA = new JSONArray(); JSONArray jArrB = new JSONArray(); JSONObject jObjA = new JSONObject(); JSONObject jObjB = new JSONObject(); JSONObject jObjC = new JSONObject(); JSONObject jObjD = new JSONObject(); JSONObject jObjE = new JSONObject(); //Erste Array aufbereiten jObjA.put("Nummer", 5); jObjA.put("val", "blaa"); jObjA.put("isOffen", true); jObjB.put("Nummer", 2); jObjB.put("val", "blaablaa"); jObjB.put("isOffen", false); jArrA.put(jObjA); jArrA.put(jObjB); //Zweite Array aufbereiten jObjC.put("Nummer", 6); jObjD.put("Nummer", 5); jObjE.put("Nummer", 2); jArrB.put(jObjC); jArrB.put(jObjD); jArrB.put(jObjE); //Ergbnis Array berechnen ermittleNeuesArray(jArrA,jArrB); } public static void ermittleNeuesArray(JSONArray jArrA, JSONArray jArrB) { int nummer,index; JSONArray jArrErgebnis = jArrB; for (int i = 0; i < jArrA.size(); i++) { nummer = jArrA.getJSONObject(i).getInt("Nummer"); index = ermittleIndexJArrB(nummer, jArrB); jArrErgebnis.getJSONObject(index).put("einKey", "123"); } System.out.println(jArrErgebnis.toString()); } public static int ermittleIndexJArrB(int nummer, JSONArray jArrB) { int index = 0; for (int i = 0; i < jArrB.size(); i++) { if (nummer == jArrB.getJSONObject(i).getInt("Nummer")) { index = i; } } return index; } }

Hier ein kleines Bildchen zur Verdeutlichung der Struktur
JsonArray.png

Viele Grüße

Markus
 
Welche Lib verwendest Du?

Ganz allgemein gesprochen, würde ich sagen: arrA in ein Set mit Nummern umwandeln. Danach über arrB iterieren und prüfen, ob Nummer im Set enthalten ist.
 
Oh wir verwenden bei dem JsonArrays unsere eigene firmeninterne Lib, ich hatte gedacht, dass das aus der Java Standardbib kommt oder so....

Aber okay das Beispiel lässt sich ja im Grunde auch auf "normale" Arrays abbilden

ich würde mir das mit Set ggf. mal ansehen, danke schon mal.
 
Wuerde ich auch so machen vom Ablauf her:

1. Array A durchlaufen.
2. Pruefen ob Objekt Ax in Array B vorkommt.
3. Wenn ja, Eigenschaften von Ax auf Bx uebertragen.

Wenn du das Array nicht als "Map" betreten kannst nach Nummern, wird es nicht viel besser.

Ein paar Anmerkungen habe ich aber zu deinem Code-Stil, auszerdem retourniert deine Suchenfunktion wenn sie nichts findet den Index "0", was ziemlich schlecht ist. Deine ermittleIndex Methode laesst sich einfacher schreiben (wenn du das erste Vorkommen willst, wovon ich ausgehen wuerde):

Java:
public static int findeIndexVon(int objektNummer, JSONArray jsonArray) {
    for (int index = 0; index < jsonArray.size(); index++) {
        JSONObject objekt = jsonArray.getJSONObject(index);
     
        if (objekt.getInt("Nummer") == objektNummer) {
            return index;
        }
   }
 
   return -1;
}

Desweiteren solltest du die Variablen dort deklarieren wo sie vorkommen, alle am Anfang zu definieren ist in Java komplett unnoetig.

Java:
public static void ermittleNeuesArray(JSONArray quellJsonArray, JSONArray zielJsonArray) {
    for (int index = 0; index < quellJsonArray.size(); index++) {
        JSONObject objekt = quellJsonArray.getJSONObject(i);
        int objektNummer = objekt.getInt("Nummer");
        int objektIndexInZiel = findeIndexVon(objektNummer, zielJsonArray);
      
        if (objektIndexInZiel >= 0) {
            JSONObject zielObjekt = zielJsonArray.getJSONObject(objektIndexInZiel);
         
            zielObjekt.put("einKey", "123");
        }
}

Wie gesagt, sieht fuer mich eigentlich gut aus.

Ob jetzt umwandeln in "Set" oder "Map" Sinn macht, kann man nur sagen wenn man den genauen Anwendungsfall kennt. Wenn das Objekt weniger als, mh, sagen wir mal als Hausnummer 1000 Eintraege hat, wuerde ich nicht ueber eine Umwandlung nachdenken weil du wahrscheinlich mehr Zeit mit wandeln als durchlaufen verbingen wirst.
 

Zurück
Oben