2016-03-23 11 views
19

Piszę aplikację na Androida za pomocą Kotlina i Królestwa. Mam JSONArray, i chcę iterację JSONObjects w tej tablicy, aby załadować je w klasie bazy Realm:Kotlin: Iteracja przez JSONArray

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

} 

The JSONArray:

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

próbowałem iteracji tak:

for (item : JSONObject in persons) { 

} 

... ale pojawia się błąd for-loop range must have an iterator() method.

+0

Jakiej biblioteki JSON używasz? – mfulton26

+0

Używam 'org.json.JSONArray' i' org.json.JSONObject'. – Ambran

Odpowiedz

27

Niestety, JsonArray nie wystawia iteratora. Więc trzeba będzie iterację używającą zakres indeksu:

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

    // Your code here 
} 
+5

Nicer to: dla (w 0 do persons.length()) –

27

Nawet jeśli niektóre klasy nie narazić metodę iterator, nadal można iteracyjne go for oświadczenie zapewniając funkcję przedłużacza iterator:

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

Teraz, gdy używasz JSONArray w for, to rozszerzenie jest wywoływane, aby uzyskać iterator. Tworzy zakres indeksów i mapuje każdy indeks do elementu odpowiadającego temu indeksowi.

Przypuszczam, że rzutowanie na JSONObject jest wymagane, ponieważ tablica może zawierać nie tylko obiekty, ale także prymitywy i inne tablice. A wywołanie asSequence jest tutaj w celu leniwego wykonania operacji map.

+1

Dzięki Ilya. Jako nowicjusz Kotlin doceniam każdy wkład, jaki mogę uzyskać. – Ambran

+0

Preferuję to rozwiązanie, ponieważ wykorzystuje ono w większym stopniu specyficzną funkcjonalność Kotlin. –

+0

Chociaż oczywiście nie zawsze będziesz mieć zestaw JSONObject. Możesz spróbować: 'operator fun JSONArray.iterator(): Iterator = (0 do długości()). AsSequence(). Map {get (it) jako T} .iterator()' teraz ma "niezaznaczone obsady" oczywiście. – user3175580