Kotlin: Iterate through a JSONArray
我正在使用Kotlin和Realm编写一个Android应用程序。
我有一个JSONArray,并且我想遍历此数组中的JSONObject以便将它们加载到Realm数据库类中:
领域类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| {
"persons":[
{
"id":0,
"name":"Biatrix"
},
{
"id":1,
"name":"Bill"
},
{
"id":2,
"name":"Oren"
},
{
"id":3,
"name":"Budd"
}
]
} |
我已经尝试过如下迭代:
1 2 3
| for (item : JSONObject in persons) {
} |
...但是出现for-loop range must have an iterator() method错误。
-
您正在使用哪个JSON库?
-
我使用org.json.JSONArray和org.json.JSONObject。
不幸的是,JsonArray没有公开迭代器。 因此,您将不得不使用索引范围遍历它:
1 2 3 4 5
| for (i in 0 until persons.length()) {
val item = persons.getJSONObject(i)
// Your code here
} |
-
更好的是:for(i in 0直到person.length())
-
for(i in 0 until persons.length()绝对更好,因为它似乎有助于避免可怕的一次性问题。但是为什么不公开迭代器呢?默认情况下,这似乎很疯狂……它是一种完全集中于多个对象的核心对象类型。遍历似乎很自然,对吧???
-
它对我有很大帮助。谢谢你
-
我超出范围异常
即使某些类未公开iterator方法,您仍然可以通过提供扩展功能iterator来使用for语句对其进行迭代:
1 2
| operator fun JSONArray.iterator(): Iterator<JSONObject>
= (0 until length()).asSequence().map { get(it) as JSONObject }.iterator() |
现在,当您在for语句中使用JsonArray时,将调用此扩展名以获取迭代器。 它创建一系列索引,并将每个索引映射到与此索引对应的项目。
我想强制转换为JSONObject是必需的,因为该数组不仅可以包含对象,而且还可以包含基元和其他数组。 而asSequence调用在这里以惰性方式执行map操作。
通用方式(假设所有数组条目均为同一类型)
1 2 3
| @Suppress("UNCHECKED_CAST")
operator fun < T > JSONArray.iterator(): Iterator< T >
= (0 until length()).asSequence().map { get(it) as T }.iterator() |
-
谢谢伊利亚。作为Kotlin的新手,我很感激我能获得的所有输入。
-
我更喜欢这种解决方案,因为它可以充分利用Kotlins的特定功能
-
当然,您不一定总是拥有JSONObject数组。您可能要尝试:operator fun < T > JSONArray.iterator(): Iterator< T > = (0 until length()).asSequence().map { get(it) as T }.iterator()现在它当然具有"未经检查的演员表"。
-
空的JSONArray的检查在哪里?如果JSONArray为空,则get(it)将引发异常。
-
如果数组为空,@ Sevastyan 0 until length()将产生一个空范围,因此在该空范围的元素上get将被调用0次(即根本不会被调用)。
-
@Ilya 0 until 0表示0,因此get(it)是get(0)。
-
@Sevastyan,您可以使用try.kotlinlang.org快速检查0 until 0的计算结果
-
此代码假定JSONArrays子级是对象,并且仅是对象。我认为,即使@androidguys的建议也假设JSONArrays子级是同质的。
-
@androidguy,可以用@Suppress("UNCHECKED_CAST")取消
怎么样
1 2 3
| (0..(jsonArray.length()-1)).forEach { i ->
var item = jsonArray.getJSONObject(i)
} |
?
-
jsonArray.getJSONObject(r)应该是jsonArray.getJSONObject(i),还是我误会了什么?
-
是的,您说对了,应该是i而不是r。固定代码示例。
-
可以细化为(0 until (jsonArray.length()))
1 2 3
| for (i in 0 until jsonArray.length()){
//do your stuff
} |
-
你能解释更多吗?
-
虽然这段代码可以解决问题,但包括解释如何以及为什么解决该问题的说明,确实可以帮助提高您的帖子质量,并可能导致更多的投票。请记住,您将来会为读者回答问题,而不仅仅是现在问的人。请编辑您的答案以添加说明,并指出适用的限制和假设。