Harshal Parekh
Harshal Parekh

Reputation: 6017

Remove all elements except one from JSONArray of JSONObjects

I have a JSONArray (org.json) like this:

[
    { "a": "a" },
    { "b": "a" },
    { "c": "a" },
    { "d": "a" },
    { "e": "a" },
    { "f": "a" },
    { "g": "a" }
]

I would like to remove all the JSONObjects that do not have the key a. Is there a better way to do other than my naive approach?

Iterator objects = jsonArray.iterator();
while (objects.hasNext()) {
    Object o = objects.next();
    if (o instanceof JSONObject && !((JSONObject) o).has("a")) {
        objects.remove();
    }
}

Expected output:

[{"a": "a"}]

Upvotes: 1

Views: 1711

Answers (3)

ETO
ETO

Reputation: 7279

If you're seeking a functional style solution, you can wrap the Iterator into a Stream and then do whatever you want.

One of the functional solutions:

JSONArray newJsonArray =
        StreamSupport.stream(jsonArray.spliterator(), false)
                     .filter(JSONObject.class::isInstance)
                     .map(JSONObject.class::cast)
                     .filter(j -> j.has("a"))
                     .collect(collectingAndThen(toList(), JSONArray::new));

Note: The solution above does not modify the original JSONArray. Following the principles of functional programming one should prefer collecting into a new object rather than modifying the existing one.

Upvotes: 2

Jason
Jason

Reputation: 5246

What we can do is map all JSONObjects to a List if they contain the key a. Then we can create a new JSONArray from that List of objects, which in this case is only 1.

You can technically do this in a single line but it looks a bit worse IMO.

List<JSONObject> objects = IntStream.range(0, array.length())
        .filter(index -> array.get(index) instanceof JSONObject)
        .mapToObj(array::getJSONObject)
        .filter(object -> object.has("a"))
        .collect(Collectors.toList());

JSONArray reduced = new JSONArray(objects);

Upvotes: 1

rxn1d
rxn1d

Reputation: 1266

If you want to avoid using type casts, try:

private static final String JSON = "{\"arr\": [" +
        "{\"z\": \"z\"}," +
        "{\"a\": \"a\"}," +
        "{\"b\": \"b\"}," +
        "{\"c\": \"c\"}" +
        "]}";
. . .
JSONObject jsonObject = new JSONObject(JSON);
JSONArray array = jsonObject.getJSONArray("arr");
JSONArray filtered = new JSONArray();

for (int i = 0; i < array.length(); i++) {
    JSONObject sub = array.getJSONObject(i);
    if (sub.has("a")) {
         filtered.put(sub);
     }
}

jsonObject.put("arr", filtered);
System.out.println(jsonObject.toString());

Result:

{"arr":[{"a":"a"}]}

Upvotes: 1

Related Questions