I have a JSONArray (org.json) like this:
[
{ \"a\": \"a\" },
{ \"b\": \"a\" },
{ \"c\": \"a\" },
{ \"d\": \"a\" },
{ \"e\": \"a\" },
{ \"
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"}]}
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.
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);