Kotlin: Iterate through a JSONArray
I'm writing an Android app using Kotlin and Realm. I have a JSONArray, and I want to iterate through the JSONObjects in this array in order to load them in a Realm database class:
Realm class:
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.Required
open class Person(
@PrimaryKey open var id: Long = 0,
@Required
open var name: String = ""
) : RealmObject() {
}
The JSONArray:
{
"persons":[
{
"id":0,
"name":"Biatrix"
},
{
"id":1,
"name":"Bill"
},
{
"id":2,
"name":"Oren"
},
{
"id":3,
"name":"Budd"
}
]
}
I've tried iterating like the following:
for (item : JSONObject in persons) {
}
... but I get a for-loop range must have an iterator() method
error.
Solution 1:
Unfortunately, JsonArray
does not expose an iterator. So you will have to iterate through it using an index range:
for (i in 0 until persons.length()) {
val item = persons.getJSONObject(i)
// Your code here
}
Solution 2:
Even if some class doesn't expose an iterator
method, you can still iterate it with for
statement by providing an extension function iterator
:
operator fun JSONArray.iterator(): Iterator<JSONObject>
= (0 until length()).asSequence().map { get(it) as JSONObject }.iterator()
Now when you use JSONArray
in for
statement this extension is invoked to get an iterator. It creates a range of indices and maps each index to an item corresponding to this index.
I suppose the cast to JSONObject
is required as the array can contain not only objects but also primitives and other arrays. And the asSequence
call is here to execute map
operation in a lazy way.
Generic way (assuming all array entries are of same type)
@Suppress("UNCHECKED_CAST")
operator fun <T> JSONArray.iterator(): Iterator<T>
= (0 until length()).asSequence().map { get(it) as T }.iterator()
Solution 3:
How about
(0..(jsonArray.length()-1)).forEach { i ->
var item = jsonArray.getJSONObject(i)
}
?