Kotlin:遍历 JSONArray
Posted
技术标签:
【中文标题】Kotlin:遍历 JSONArray【英文标题】:Kotlin: Iterate through a JSONArray 【发布时间】:2016-07-11 03:01:17 【问题描述】:我正在使用 Kotlin 和 Realm 编写一个 android 应用程序。 我有一个 JSONArray,我想遍历这个数组中的 JSONObject,以便将它们加载到 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
错误。
【问题讨论】:
您使用的是哪个 JSON 库? 我使用org.json.JSONArray
和org.json.JSONObject
。
【参考方案1】:
不幸的是,JsonArray
没有公开迭代器。所以你必须使用索引范围来遍历它:
for (i in 0 until persons.length())
val item = persons.getJSONObject(i)
// Your code here
【讨论】:
更好的是:for(i in 0 until persons.length())for(i in 0 until persons.length()
肯定更好,因为它似乎有助于避免可怕的一对一问题。但是为什么不暴露迭代器呢?默认情况下这似乎很疯狂……它是一种完全专注于多个对象的核心对象类型。迭代似乎很自然,对吧???
对我帮助很大。谢谢大佬。
我超出范围异常
这是错误的方向......请删除这个错误的答案。声明很容易自己声明一个 iterator() fun 的说法更有帮助!【参考方案2】:
即使某些类没有公开iterator
方法,您仍然可以通过提供扩展函数iterator
使用for
语句对其进行迭代:
operator fun JSONArray.iterator(): Iterator<JSONObject>
= (0 until length()).asSequence().map get(it) as JSONObject .iterator()
现在,当您在 for
语句中使用 JSONArray
时,会调用此扩展来获取迭代器。它创建一系列索引并将每个索引映射到与该索引对应的项目。
我认为转换为JSONObject
是必需的,因为数组不仅可以包含对象,还可以包含基元和其他数组。而asSequence
调用就是在这里偷懒执行map
操作。
通用方式(假设所有数组条目的类型相同)
@Suppress("UNCHECKED_CAST")
operator fun <T> JSONArray.iterator(): Iterator<T>
= (0 until length()).asSequence().map get(it) as T .iterator()
【讨论】:
谢谢伊利亚。作为一名 Kotlin 新手,我很感激我能得到的每一个意见。 我更喜欢这个解决方案,因为它更好地利用了 Kotlin 的特定功能 当然你不会总是有一个 JSONObject 数组。你可能想试试:operator fun <T> JSONArray.iterator(): Iterator<T> = (0 until length()).asSequence().map get(it) as T .iterator()
现在它当然有一个“未经检查的演员表”。
如果数组为空,@Sevastyan 0 until length()
将产生一个空范围,因此 get
将在空范围的元素上被调用 0 次(即根本不会被调用)。
@Sevastyan 你可以用try.kotlinlang.org快速检查0 until 0
的结果【参考方案3】:
怎么样
(0..(jsonArray.length()-1)).forEach i ->
var item = jsonArray.getJSONObject(i)
?
【讨论】:
jsonArray.getJSONObject(r)
应该是 jsonArray.getJSONObject(i)
还是我误解了什么?
是的,你是对的,应该是i
而不是r
。固定代码示例。
可以细化为(0 until (jsonArray.length()))
感谢您提供答案。您能否编辑您的答案以包括对您的代码的解释?【参考方案4】:
for (i in 0 until jsonArray.length())
//do your stuff
【讨论】:
你能再解释一下吗? 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释,并说明适用的限制和假设。【参考方案5】:最短的方法是:
(0 until persons.length()).forEach
val item = persons.getJSONObject(it)
基本上从 0 到 jsonarray 长度的范围,它每次取一个数字并将其用作检索当前对象的索引
【讨论】:
感谢您提供答案。您能否编辑您的答案以包括对您的代码的解释?这将有助于未来的读者更好地了解正在发生的事情,尤其是那些刚接触该语言并难以理解概念的社区成员。 感谢您提供答案。您能否编辑您的答案以包括对您的代码的解释?以上是关于Kotlin:遍历 JSONArray的主要内容,如果未能解决你的问题,请参考以下文章
对比Java学Kotlin震惊!Kotlin 竟然废弃了循环遍历?!
对比Java学Kotlin震惊!Kotlin 竟然废弃了循环遍历?!
使用Kotlin中的foreach循环遍历BigInteger值
Kotlin集合操作 ③ ( List 集合遍历 | for in | forEach | forEachIndexed | List 通过解构一次性给多个元素赋值 )
Kotlin集合操作 ③ ( List 集合遍历 | for in | forEach | forEachIndexed | List 通过解构一次性给多个元素赋值 )