New2Java
New2Java

Reputation: 313

How to efficiently merge two JSON Strings based on a common key

I have two JSON strings which are essentially arrays of JSONObject. The two JSON strings have below structure and keys:

JSON-1:

[
    {
        "title": "ABC",
        "edition": 7,
        "year": 2011
    },
    {
        "title": "DEF",
        "edition": 2,
        "year": 2012
    },
    {
        "title": "XYZ",
        "edition": 3,
        "year": 2013
    }
]

And, JSON-2:

[
    {
        "title": "ABC",
        "price": "20"
    },
    {
        "title": "DEF",
        "price": "20"
    },
    {
        "title": "XYZ",
        "price": "20"
    }
]

Both these JSONs have a common key "title" based on which I want to merge these two JSONs, either merging JSON-2 values into JSON-1 or creating a JSON object with the merged result.

The merged result should look like below:

[
    {
        "title": "ABC",
        "edition": 7,
        "year": 2011,
        "price": "20"
    },
    {
        "title": "DEF",
        "edition": 2,
        "year": 2012
        "price": "20"
    },
    {
        "title": "XYZ",
        "edition": 3,
        "year": 2013
        "price": "20"
    }
]

How can I achieve this by minimum looping and minimum object creation? I also can not use entity/model classes. The idea is to do it without creating any model classes.

Note: I cannot use Gson because I don't have the approval to use the same.

  1. I tried to use List<JSONObject> listObj = objectMapper.readValue(jsonOneString, new TypeReference<List<JSONObject>>(){});, but I am getting an unknown property exception.

  2. I tried JsonNode node = objectMapper.readTree(jsonOneString);, but I cannot proceed much further with this approach.

I know what I am doing here is highly inefficient, so looking for ways which will use no entity class, minimum new object creation and minimum loops. Kindly advise.

UPDATE: I updated the below code with a slight modification:

if (json1elem.get("title")!=null 
        && json2elem.get("title")!=null 
            && json1elem.get("title").equals(json2elem.get("title"))) {

    //
}

Upvotes: 0

Views: 1722

Answers (2)

sagar mulay
sagar mulay

Reputation: 1

public static JSONObject deepMerge(JSONObject source, JSONObject target) throws JSONException {
        Iterator it = source.keys();
        while (it.hasNext()) {
            String key = (String) it.next();
            Object value = source.get(key);
            if (!target.has(key)) {
                target.put(key, value);
            } else {
                if (value instanceof JSONArray) {
                    JSONArray valueArry = (JSONArray) value;
                    for (int i = 0; i < valueArry.length(); i++) {
                        if (valueArry.get(i) instanceof JSONObject) {
                            JSONObject jsonObj = (JSONObject) valueArry.get(i);
                            JSONObject valueJson1 = (JSONObject) jsonObj;
                            JSONArray targetArray = target.getJSONArray(key);
                            deepMerge(valueJson1, targetArray.getJSONObject(i));
                        }
                    }
                } else if (value instanceof JSONObject) {
                    JSONObject valueJson = (JSONObject) value;
                    deepMerge(valueJson, target.getJSONObject(key));
                } else {
                    target.put(key, value);
                }
            }
        }
        return target;
    }

Upvotes: 0

Raymond Choi
Raymond Choi

Reputation: 1271

JsonNode json1 = objectMapper.readTree(jsonOneString);
JsonNode json2 = objectMapper.readTree(jsonTwoString);
for (JsonNode json1elem : json1) {
    for (JsonNode json2elem : json2) {
        if (json1elem.get("title").equals(json2elem.get("title"))) {
            ((ObjectNode) json1elem).setAll((ObjectNode) json2elem);
            break;
        }
    }
}
System.out.println(json1.toPrettyString());

Upvotes: 0

Related Questions