Kotlin: Iterate over components of object

后端 未结 3 1289
长发绾君心
长发绾君心 2020-12-30 20:55

Each data class object has a component for each property like component1, component2, etc.. I was wondering if there is any way in Kotlin to iterate over each component of a

相关标签:
3条回答
  • 2020-12-30 21:39

    First of all, the componentN properties are available only on data classes, not on every object.

    There is no API specifically for iterating over the components, but you can use the Kotlin reflection to iterate over properties of any class:

    class User(val age: Int, val name: String)
    
    fun main(args: Array<String>) {
        val user = User(25, "Bob")
        for (prop in User::class.memberProperties) {
            println("${prop.name} = ${prop.get(user)}")
        }  
    }
    
    0 讨论(0)
  • 2020-12-30 21:47

    here is an idea...i am not satisfied with it...but nonetheless here it is.

    it has some pros and cons:

    • pros:
      • type-safe/compile-time checks
        • adding/removing fields to/from the data class causes compiler errors at field-iteration sites
      • no boiler-plate code needed
    • cons:
      • won't work if default values are defined for arguments

    declaration:

    data class Memento(
        val testType: TestTypeData,
        val notes: String,
        val examinationTime: MillisSinceEpoch?,
        val administeredBy: String,
        val signature: SignatureViewHolder.SignatureData,
        val signerName: String,
        val signerRole: SignerRole
    ) : Serializable
    

    iterating through all fields:

    val iterateThroughAllMyFields: Memento = someValue
    Memento(
        testType = iterateThroughAllMyFields.testType.also { testType ->
            // do something with testType
        },
        notes = iterateThroughAllMyFields.notes.also { notes ->
            // do something with notes
        },
        examinationTime = iterateThroughAllMyFields.examinationTime.also { examinationTime ->
            // do something with examinationTime
        },
        administeredBy = iterateThroughAllMyFields.administeredBy.also { administeredBy ->
            // do something with administeredBy
        },
        signature = iterateThroughAllMyFields.signature.also { signature ->
            // do something with signature
        },
        signerName = iterateThroughAllMyFields.signerName.also { signerName ->
            // do something with signerName
        },
        signerRole = iterateThroughAllMyFields.signerRole.also { signerRole ->
            // do something with signerRole
        }
    )
    
    0 讨论(0)
  • 2020-12-30 21:51

    also, you can use Properties Delegation with built-in delegate 'by map'. it's very useful for some simple stat classes.

    class DbUsingStat {
      private val map = mutableMapOf(
        "removed" to 0,
        "updated" to 0,
        "skipped" to 0
      )
    
      var removed by map
      var updated by map
      var skipped by map
    
      fun asMap() : Map<String, Int> = map.toMap()
    }
    
    ...
    ...
    
    
    val someStatistic = DbUsingStat().apply {
      skipped = 5
      removed = 10
      updated = 1505
    }
    
    for((k, v) in someStatistic.asMap())
      println("$k: $v")
    
    0 讨论(0)
提交回复
热议问题