Ich schreibe eine Android-App mit Kotlin und Realm. Ich habe ein JSONArray und möchte die JSONObjects in diesem Array durchlaufen, um sie in eine Realm-Datenbankklasse zu laden:
Reichsklasse:
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() {
}
Das JSONArray:
{
"persons":[
{
"id":0,
"name":"Biatrix"
},
{
"id":1,
"name":"Bill"
},
{
"id":2,
"name":"Oren"
},
{
"id":3,
"name":"Budd"
}
]
}
Ich habe versucht, wie folgt zu iterieren:
for (item : JSONObject in persons) {
}
... aber ich bekomme eine for-loop range must have an iterator() method
Fehlermeldung.
org.json.JSONArray
undorg.json.JSONObject
.Antworten:
Leider wird
JsonArray
kein Iterator verfügbar gemacht. Sie müssen es also mithilfe eines Indexbereichs durchlaufen:for (i in 0 until persons.length()) { val item = persons.getJSONObject(i) // Your code here }
quelle
for(i in 0 until persons.length()
ist definitiv schöner, da es zu helfen scheint, das gefürchtete Einzelproblem zu vermeiden. Aber warum sollte ein Iterator nicht entlarvt werden? Dies scheint standardmäßig verrückt zu sein ... es ist ein Kernobjekttyp, der sich vollständig auf mehrere Objekte konzentriert. Durchlaufen scheint nur natürlich, oder ???Auch wenn eine Klasse eine
iterator
Methode nicht verfügbar macht , können Sie sie dennoch mit einerfor
Anweisung iterieren, indem Sie eine Erweiterungsfunktion bereitstelleniterator
:operator fun JSONArray.iterator(): Iterator<JSONObject> = (0 until length()).asSequence().map { get(it) as JSONObject }.iterator()
Jetzt, wenn Sie
JSONArray
in verwendenfor
Anweisung verwenden, wird diese Erweiterung aufgerufen, um einen Iterator zu erhalten. Es erstellt eine Reihe von Indizes und ordnet jeden Index einem Element zu, das diesem Index entspricht.Ich nehme an, die Umwandlung in
JSONObject
ist erforderlich, da das Array nicht nur Objekte, sondern auch Grundelemente und andere Arrays enthalten kann. Und derasSequence
Aufruf ist hier, um diemap
Operation auf faule Weise auszuführen .Generischer Weg ( vorausgesetzt, alle Array-Einträge sind vom gleichen Typ)
@Suppress("UNCHECKED_CAST") operator fun <T> JSONArray.iterator(): Iterator<T> = (0 until length()).asSequence().map { get(it) as T }.iterator()
quelle
operator fun <T> JSONArray.iterator(): Iterator<T> = (0 until length()).asSequence().map { get(it) as T }.iterator()
Jetzt hat es natürlich eine "ungeprüfte Besetzung".0 until length()
erzeugt einen leeren Bereich, wenn ein Array leer ist, undget
wird daher 0-mal (dh überhaupt nicht aufgerufen) für Elemente des leeren Bereichs aufgerufen.0 until 0
mit try.kotlinlang.orgWie wäre es mit
(0..(jsonArray.length()-1)).forEach { i -> var item = jsonArray.getJSONObject(i) }
?
quelle
jsonArray.getJSONObject(r)
solltejsonArray.getJSONObject(i)
oder habe ich etwas falsch verstanden?i
nicht seinr
. Codebeispiel behoben.(0 until (jsonArray.length()))
for (i in 0 until jsonArray.length()){ //do your stuff }
quelle