Котлин: Итерации через JSONArray

Я пишу приложение для Android, используя Kotlin и Realm. У меня есть JSONArray, и я хочу выполнить итерацию через JSONObjects в этом массиве, чтобы загрузить их в класс базы данных Realm:

Класс области:

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() {

}

JSONArray:

{
    "persons":[
        {
           "id":0,
           "name":"Biatrix"
        },
        {
           "id":1,
           "name":"Bill"
        },
        {
           "id":2,
           "name":"Oren"
        },
        {
           "id":3,
           "name":"Budd"
        }
    ]
}

Я пробовал итерацию следующим образом:

for (item : JSONObject in persons) {

}

... но я получаю ошибку for-loop range must have an iterator() method.

Ответы

Ответ 1

К сожалению, JsonArray не предоставляет итератор. Поэтому вам придется перебирать его, используя диапазон индексов:

for (i in 0 until persons.length())) {
    val item = persons.getJSONObject(i)

    // Your code here
}

Ответ 2

Даже если какой-либо класс не выставляет метод iterator, вы все равно можете его перебирать с помощью инструкции for, предоставляя функцию расширения iterator:

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

Теперь, когда вы используете оператор JSONArray в for, это расширение вызывается для получения итератора. Он создает ряд индексов и сопоставляет каждый индекс с элементом, соответствующим этому индексу.

Я полагаю, что приведение к JSONObject требуется, поскольку массив может содержать не только объекты, но также примитивы и другие массивы. И вызов asSequence предназначен для выполнения операции map ленивым способом.

Ответ 3

Как насчет

(0..(jsonArray.length()-1)).forEach { i ->
    var item = jsonArray.getJSONObject(i)
}

?

Ответ 4

for (i in 0 until jsonArray.length()){
    //do your stuff
    }