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.JSONArrayorg.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 &lt;T&gt; JSONArray.iterator(): Iterator&lt;T&gt; = (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 MutableList的遍历

使用Kotlin中的foreach循环遍历BigInteger值

Kotlin集合操作 ③ ( List 集合遍历 | for in | forEach | forEachIndexed | List 通过解构一次性给多个元素赋值 )

Kotlin集合操作 ③ ( List 集合遍历 | for in | forEach | forEachIndexed | List 通过解构一次性给多个元素赋值 )