1. Introduction

In this tutorial, we’ll illustrate how to iterate over a JSONArray.

First, we’ll try to do it with a for loop. Then, we’ll look at how to make an extension function and make it even easier.

2. Iterating Through a JSONArray

The JSONArray class doesn’t implement the iterator operator. Hence, we can’t use the typical for-each pattern to iterate a JSONArray.

Let’s look at some other ways which we can use instead.

2.1. Iterating via a for Loop

We can iterate through a JSONArray using a for loop:

val booksJSONArray = JSONArray(BOOKS_STRING)
for (i in 0 until booksJSONArray.length()) {
    val book = booksJSONArray.getJSONObject(i)
    println("${book.get("book_name")} by ${book.get("author")}")
}

We can also use a for-each loop:

val booksJSONArray = JSONArray(BOOKS_STRING)
(0 until booksJSONArray.length()).forEach {
    val book = booksJSONArray.getJSONObject(it)
    println("${book.get("book_name")} by ${book.get("author")}")
}

This makes things a bit more readable. But, it is still not as intuitive as using an iterator.

2.2. Adding a Convenient Extension Function

A typical iteration pattern looks like this:

val numbers = arrayListOf(1,2)
for (number in numbers){
    ...
}

Here, we can use this pattern because ArrayList implements Iterable. Sadly, JSONArray doesn’t implement it*.*

However, we can use extension functions to make this work:

operator fun <T> JSONArray.iterator(): Iterator<T> =
  (0 until this.length()).asSequence().map { this.get(it) as T }.iterator()

Here, we add the iterator operator to JSONArray. Finally, this lets us loop over it like the usual way:

for (book in booksJSONArray) {
    println("${(book as JSONObject).get("book_name")} by ${(book as JSONObject).get("author")}")
}

3. Conclusion

To summarise, JSONArray does not expose an iterator. As shown above, one option is to use for-loops. Also, we can retrofit it with an iterator using extension functions.

As always code examples are available over on GitHub.